Repository navigation
Conversation
`AttrListTreeprocessor.BASE_RE` matched the attribute content with
`([^\}\n ][^\n]*)` and then allowed trailing spaces before the closing
brace with a separate `[ ]*`. Because `[^\n]*` already matches spaces,
the two groups both cover the same run of trailing spaces. When a block
ends with an unclosed attribute list, the closing brace is never found,
so for a run of n spaces the engine retries the match from each of the
n+1 ways to split the spaces between the two groups, which is O(n^2).
The trailing `[ ]*` can only ever match zero characters in a successful
match (the greedy `[^\n]*` consumes the spaces first), so dropping it
leaves every match and capture group unchanged while removing the
ambiguity. A two-line block such as `text\n{a` followed by 200k spaces
drops from ~10s to ~20ms, and the cost is now linear in the input size.
|
Please review our AI Policy. Specifically, the following:
You description reads like it was written by AI. Also, as the PR template was deleted, I am assuming you had AI autonomously submit the PR. This presents 3 problems:
That said, it is possible that this was not AI generated. If you can honestly confirm that, then we will proceed. Otherwise, this will be closed. PS to other maintainers: this is going to be my standard response to AI submitted PRs/issues from now on. Feel free to respond in kind if you see a new PR first. |
|
Hi @waylan, I apologize for this, I used AI for the wordings and stuff and pasted it without noticing. If the policy means this has to be closed, I understand. I’m happy to resubmit with the template filled in and the AI use disclosed, or to open an issue instead so a maintainer can make the fix. |
When the
attr_listextension is enabled,AttrListTreeprocessor.BASE_REmatches the attribute content with([^}\n ][^\n]*)and then allows trailing spaces before the closing brace with a separate[ ]*.[^\n]*already matches spaces, so both groups cover the same run of trailing spaces. When a block ends with an unclosed attribute list the closing brace is never found, and for a run of n spaces the engine retries the match from each of the n+1 ways to split the spaces between the two groups, which is O(n^2).Markdown is routinely used to render untrusted input server-side, so this is reachable pre-auth as an algorithmic-complexity DoS (CWE-1333/CWE-407). A two-line block such as
text {afollowed by a long run of spaces hitsBLOCK_RE, which is built fromBASE_RE;HEADER_REandINLINE_REshare the same shape.Measured with
markdown.markdown(text, extensions=['attr_list'])on'text {a' + ' ' * n:The trailing
[ ]*can only ever match zero characters in a successful match, because the greedy[^\n]*consumes the trailing spaces first and then gives back exactly enough for\}to match. Dropping it removes the ambiguity and makes the match linear. I verified the old and new patterns produce identical spans and capture groups across ~16k inputs (valid attribute lists, the existing test cases, and random brace/space/tab strings), so valid input is unaffected. Added a regression test and ran the full test suite and flake8.This is the same class of defect fixed for
ReferenceProcessorin #798.