fixup! TF-4224 Reduce ReDoS vulnerability

This commit is contained in:
Dang Dat
2026-01-05 17:01:59 +07:00
committed by Dat H. Pham
parent b4fdc55a07
commit 060416292f
4 changed files with 59 additions and 4 deletions
@@ -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.
@@ -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<void> process({
required Document document,
+9
View File
@@ -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 => {
+42 -4
View File
@@ -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');
});
});
});