Repository navigation
Conversation
`HTMLExtractor.parse_comment` searches for `-->` (or `--!>`) from each `<!--` to the end of the raw data. When there is none, it passes `<` through as data and returns `i + 1`, so the next `<!--` repeats the same failing scan. A run of n unclosed comments therefore costs O(n^2): `'<!--' * 32000` (125 KB) takes about 5 seconds to convert and 250 KB takes about 22 seconds. If no close exists after some position in `rawdata`, none exists after any later position in the same string either. The parser now records the string and position of the last failed search and skips the search when it would start at or after that position. The string is compared by identity so the record is never reused for different raw data. Output is unchanged.
|
Sigh. Some of these optimizations you submit seem so convoluted to me. I think: No one in the real world would ever actually try that. But, now that it is a known issue, someone could use it in a DOS attach on a server which parses untrusted Markdown. So I guess we should apply the patch. As a reminder to myself, the spellcheck failure is for Maybe we could slow down to one outstanding PR at a time? The constant stream of PRs to review can be overwhelming. |
|
I agree about the constant onslaught of PRs. Now with AI driven PRs, it's so low cost for people to pump them out, but more expensive (time wise) for projects that are doing thorough analysis of the PRs before merging. I've probably had more PRs across my projects in the past month then I normally receive for an entire year. |
|
Fair point on the pace, sorry about the pile-up. I'll hold off on opening anything new until #1664, #1673 and this one are through, and keep it to one outstanding PR at a time after that. On the spellcheck: if #1664 ends up stalling, I can add |
|
Except for the spelling error, this one is ready to go. If you want, you can apply the change here, and I'll merge this. Then after its merged you could address the merge conflict in #1664. Or you can leave it as-is. Your choice. |
Description
HTMLExtractor.parse_commentsearches for a comment close from each<!--to the end of the raw data. When there isn't one, it passes<through as data and moves forward one character, so the next<!--runs the same failing search again. n unclosed comments cost O(n^2) with no extensions enabled:'<!--' * 8000(31 KB)'<!--' * 16000(62 KB)'<!--' * 32000(125 KB)'<!--' * 64000(250 KB)If no close exists after some position in
rawdata, none exists after any later position in the same string. The parser now records the last failed search (therawdatastring, compared by identity, and the start position) and skips any later search that would start at or after it. The rest of the method is unchanged. Processing instructions, declarations, CDATA and end tags don't show this behavior, so onlyparse_commentneeded the change.Output is unchanged. I compared the rendered HTML with master on about 115k random documents built from comment, tag, code span and blank line fragments, using no extensions,
md_in_htmlandextra, on Python 3.11 and 3.14. The full test suite passes on 3.11, 3.13 and 3.14, and with Pygments 2.7.1. flake8 is clean. The new test takes about 13 s on master and 0.06 s with this change.AI Assistance Disclosure
No AI tools were used in preparing this PR.
AI tools were used and I have disclosed which ones, and have fully reviewed and verified their output.
AI tools were use to assist with the following:
Checklist