Skip to content

Commit 6ddd382

Browse files
committed
fix: don't leak HTML comment content into pasted paragraph text
_parseDeltaElement's fallback branch called child.text on any non-Element DOM node, including dom.Comment (whose .text getter aliases its raw data). This let real HTML comments -- e.g. the internal tracking marker Google's AI Overview panel injects when you copy its answer text -- surface as visible garbage in the editor. Skip non-Text nodes here, matching the dom.Text check _parseElement already does one level up.
1 parent 5f1d968 commit 6ddd382

2 files changed

Lines changed: 20 additions & 2 deletions

File tree

lib/src/plugins/html/html_document_decoder.dart

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -439,9 +439,11 @@ class DocumentHTMLDecoder extends Converter<String, Document> {
439439
);
440440
}
441441
}
442-
} else {
443-
delta.insert(child.text?.replaceAll(RegExp(r'\n+$'), '') ?? '');
442+
} else if (child is dom.Text) {
443+
delta.insert(child.text.replaceAll(RegExp(r'\n+$'), ''));
444444
}
445+
// other node types (e.g. dom.Comment) carry no visible content and
446+
// are intentionally skipped, mirroring _parseElement's handling.
445447
}
446448
return (delta, nodes);
447449
}

test/customer/html_document_test.dart

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,5 +41,21 @@ void main() {
4141
isTrue,
4242
);
4343
});
44+
45+
test('paste text with an inline HTML comment does not leak comment text',
46+
() {
47+
// Some sites (e.g. Google Search AI Overview) inject an HTML comment
48+
// into copied content as an internal marker. It must not surface as
49+
// visible text, regardless of what the comment contains.
50+
const html = '''
51+
<p>First answer<!--TgQPHd||[]--></p>
52+
<p>Second answer<!-- some other internal marker --></p>
53+
''';
54+
final document = htmlToDocument(html);
55+
final children = document.root.children;
56+
57+
expect(children[0].delta!.toPlainText(), 'First answer');
58+
expect(children[1].delta!.toPlainText(), 'Second answer');
59+
});
4460
});
4561
}

0 commit comments

Comments
 (0)