diff --git a/core/lib/presentation/utils/html_transformer/base/dom_transformer.dart b/core/lib/presentation/utils/html_transformer/base/dom_transformer.dart
index 28e5fcb57..ceeac3d1d 100644
--- a/core/lib/presentation/utils/html_transformer/base/dom_transformer.dart
+++ b/core/lib/presentation/utils/html_transformer/base/dom_transformer.dart
@@ -2,6 +2,7 @@
import 'package:core/data/network/dio_client.dart';
import 'package:core/utils/app_logger.dart';
import 'package:dartz/dartz.dart';
+import 'package:flutter/widgets.dart' show visibleForTesting;
import 'package:html/dom.dart';
/// Transforms the HTML DOM.
@@ -11,6 +12,9 @@ abstract class DomTransformer {
static final _backgroundImageRegex = RegExp(r'''\bbackground-image\s*:\s*url\(\s*['"]?([^' ")]+)['"]?\s*\)''');
+ @visibleForTesting
+ static RegExp get backgroundImageRegex => _backgroundImageRegex;
+
/// Uses the `DOM` [document] to transform the `document`.
///
/// All changes will be visible to subsequent transformers.
diff --git a/core/lib/presentation/utils/html_transformer/dom/normalize_line_height_in_style_transformer.dart b/core/lib/presentation/utils/html_transformer/dom/normalize_line_height_in_style_transformer.dart
index 53eccd7c8..f78d132bd 100644
--- a/core/lib/presentation/utils/html_transformer/dom/normalize_line_height_in_style_transformer.dart
+++ b/core/lib/presentation/utils/html_transformer/dom/normalize_line_height_in_style_transformer.dart
@@ -1,6 +1,7 @@
import 'package:core/data/network/dio_client.dart';
import 'package:core/presentation/utils/html_transformer/base/dom_transformer.dart';
import 'package:core/utils/app_logger.dart';
+import 'package:flutter/widgets.dart' show visibleForTesting;
import 'package:html/dom.dart';
class NormalizeLineHeightInStyleTransformer extends DomTransformer {
@@ -15,6 +16,9 @@ class NormalizeLineHeightInStyleTransformer extends DomTransformer {
caseSensitive: false,
);
+ @visibleForTesting
+ static RegExp get lineHeightPattern => _lineHeightPattern;
+
@override
Future process({
required Document document,
diff --git a/core/lib/utils/html/html_utils.dart b/core/lib/utils/html/html_utils.dart
index 794f5fb9c..627ea2580 100644
--- a/core/lib/utils/html/html_utils.dart
+++ b/core/lib/utils/html/html_utils.dart
@@ -39,6 +39,15 @@ class HtmlUtils {
caseSensitive: false,
);
+ @visibleForTesting
+ static RegExp get htmlStartTagRegex => _htmlStartTagRegex;
+
+ @visibleForTesting
+ static RegExp get htmlEndTagRegex => _htmlEndTagRegex;
+
+ @visibleForTesting
+ static RegExp get urlRegex => _urlRegex;
+
static const removeLineHeight1px = (
script: '''
document.querySelectorAll('[style*="line-height"]').forEach(el => {
diff --git a/core/test/utils/redos_vulnerability_test.dart b/core/test/utils/redos_vulnerability_test.dart
index 2cba1ab11..bd1b78310 100644
--- a/core/test/utils/redos_vulnerability_test.dart
+++ b/core/test/utils/redos_vulnerability_test.dart
@@ -1,4 +1,5 @@
import 'package:core/data/network/dio_client.dart';
+import 'package:core/presentation/utils/html_transformer/base/dom_transformer.dart';
import 'package:core/presentation/utils/html_transformer/dom/image_transformers.dart';
import 'package:core/presentation/utils/html_transformer/dom/normalize_line_height_in_style_transformer.dart';
import 'package:core/utils/html/html_utils.dart';
@@ -684,10 +685,47 @@ void main() {
group('Regex initialization optimization', () {
test('regex patterns should be reused, not recreated', () {
- // This test verifies that regex patterns are static and reused
- final regex1 = StringConvert.base64ValidationRegex;
- final regex2 = StringConvert.base64ValidationRegex;
- expect(identical(regex1, regex2), true);
+ // This test verifies that all refactored regex patterns are static and reused
+ // across multiple calls, preventing unnecessary regex compilation overhead
+
+ // StringConvert patterns
+ final base64_1 = StringConvert.base64ValidationRegex;
+ final base64_2 = StringConvert.base64ValidationRegex;
+ expect(identical(base64_1, base64_2), true,
+ reason: 'base64ValidationRegex should be static and reused');
+
+ final emailLocalhost1 = StringConvert.emailLocalhostRegex;
+ final emailLocalhost2 = StringConvert.emailLocalhostRegex;
+ expect(identical(emailLocalhost1, emailLocalhost2), true,
+ reason: 'emailLocalhostRegex should be static and reused');
+
+ // DomTransformer patterns
+ final bgImage1 = DomTransformer.backgroundImageRegex;
+ final bgImage2 = DomTransformer.backgroundImageRegex;
+ expect(identical(bgImage1, bgImage2), true,
+ reason: 'backgroundImageRegex should be static and reused');
+
+ // NormalizeLineHeightInStyleTransformer patterns
+ final lineHeight1 = NormalizeLineHeightInStyleTransformer.lineHeightPattern;
+ final lineHeight2 = NormalizeLineHeightInStyleTransformer.lineHeightPattern;
+ expect(identical(lineHeight1, lineHeight2), true,
+ reason: 'lineHeightPattern should be static and reused');
+
+ // HtmlUtils patterns
+ final htmlStartTag1 = HtmlUtils.htmlStartTagRegex;
+ final htmlStartTag2 = HtmlUtils.htmlStartTagRegex;
+ expect(identical(htmlStartTag1, htmlStartTag2), true,
+ reason: 'htmlStartTagRegex should be static and reused');
+
+ final htmlEndTag1 = HtmlUtils.htmlEndTagRegex;
+ final htmlEndTag2 = HtmlUtils.htmlEndTagRegex;
+ expect(identical(htmlEndTag1, htmlEndTag2), true,
+ reason: 'htmlEndTagRegex should be static and reused');
+
+ final urlRegex1 = HtmlUtils.urlRegex;
+ final urlRegex2 = HtmlUtils.urlRegex;
+ expect(identical(urlRegex1, urlRegex2), true,
+ reason: 'urlRegex should be static and reused');
});
});
});