From 5354daf618149f92580a1407c036115753c5df73 Mon Sep 17 00:00:00 2001 From: facelessuser Date: Thu, 25 Sep 2025 14:39:25 -0600 Subject: [PATCH] Fix an HTML comment parsing case that can cause an infinite loop Fixes #1554 --- docs/changelog.md | 6 ++++++ markdown/htmlparser.py | 19 +++++++++++++++++++ tests/test_syntax/blocks/test_html_blocks.py | 18 +++++++++++++++++- 3 files changed, 42 insertions(+), 1 deletion(-) diff --git a/docs/changelog.md b/docs/changelog.md index 00c7b5e1b..cd6c8ec82 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -10,6 +10,12 @@ and this project adheres to the [Python Version Specification](https://packaging.python.org/en/latest/specifications/version-specifiers/). See the [Contributing Guide](contributing.md) for details. +## [Unreleased] + +### Fixed + +* Fix an HTML comment parsing case in some Python versions that can cause an infinite loop (#1554). + ## [3.9.0] - 2025-09-04 ### Changed diff --git a/markdown/htmlparser.py b/markdown/htmlparser.py index 63e5df31b..658cd37e0 100644 --- a/markdown/htmlparser.py +++ b/markdown/htmlparser.py @@ -33,6 +33,9 @@ if TYPE_CHECKING: # pragma: no cover from markdown import Markdown +# Included for versions which do not have current comment fix +commentclose = re.compile(r'--!?>') +commentabruptclose = re.compile(r'-?>') # Import a copy of the html.parser lib as `htmlparser` so we can monkeypatch it. # Users can still do `from html import parser` and get the default behavior. @@ -302,6 +305,22 @@ def parse_pi(self, i: int) -> int: self.handle_data(' int: if self.at_line_start() or self.intail: if self.rawdata[i:i+3] == ' + Some content after the bad comment. + """ + ), + self.dedent( + """ +

<!-- This comment is malformed and never closes -- > + Some content after the bad comment.

+ """ + ) + ) + def test_raw_processing_instruction_one_line(self): self.assertMarkdownRenders( "'; ?>",