Skip to content

Commit c3c710f

Browse files
miss-islingtonserhiy-storchakaclaude
authored
[3.14] gh-135661: Fix abrupt closing of empty comment in HTMLParser (GH-153007) (GH-153025)
An abruptly closed empty comment ("<!-->" or "<!--->") no longer extends up to a later "-->" in the same feed() call. test_htmlparser now also feeds each string source as a single chunk, in addition to one character at a time, to exercise different input buffering. (cherry picked from commit ed370d3) Co-authored-by: Serhiy Storchaka <storchaka@gmail.com> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
1 parent d786fbd commit c3c710f

3 files changed

Lines changed: 17 additions & 2 deletions

File tree

Lib/html/parser.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -387,9 +387,11 @@ def parse_html_declaration(self, i):
387387
def parse_comment(self, i, report=True):
388388
rawdata = self.rawdata
389389
assert rawdata.startswith('<!--', i), 'unexpected call to parse_comment()'
390-
match = commentclose.search(rawdata, i+4)
390+
# An empty comment is abruptly closed by the first ">" or "->",
391+
# taking priority over a later "-->" or "--!>" close.
392+
match = commentabruptclose.match(rawdata, i+4)
391393
if not match:
392-
match = commentabruptclose.match(rawdata, i+4)
394+
match = commentclose.search(rawdata, i+4)
393395
if not match:
394396
return -1
395397
if report:

Lib/test/test_htmlparser.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,11 @@ def _run_check(self, source, expected_events,
116116
*, collector=None, convert_charrefs=False):
117117
if collector is None:
118118
collector = self.get_collector(convert_charrefs=convert_charrefs)
119+
if isinstance(source, str):
120+
# Also feed the whole string at once, not just character by
121+
# character (below), to exercise different input buffering.
122+
self._run_check([source], expected_events,
123+
convert_charrefs=convert_charrefs)
119124
parser = collector
120125
for s in source:
121126
parser.feed(s)
@@ -593,6 +598,9 @@ def test_comments(self):
593598
'<!-- <!-- nested --> -->'
594599
'<!--<!-->'
595600
'<!--<!--!>'
601+
# abruptly closed empty comment must not swallow later text
602+
'<!-->x-->'
603+
'<!--->y-->'
596604
)
597605
expected = [('comment', " I'm a valid comment "),
598606
('comment', 'me too!'),
@@ -613,6 +621,8 @@ def test_comments(self):
613621
('comment', ' <!-- nested '), ('data', ' -->'),
614622
('comment', '<!'),
615623
('comment', '<!'),
624+
('comment', ''), ('data', 'x-->'),
625+
('comment', ''), ('data', 'y-->'),
616626
]
617627
self._run_check(html, expected)
618628

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Fix :class:`html.parser.HTMLParser`: an abruptly closed empty comment
2+
(``<!-->`` or ``<!--->``) no longer extends up to a later ``-->`` in the same
3+
:meth:`~html.parser.HTMLParser.feed` call.

0 commit comments

Comments
 (0)