Skip to content

Skip the backslash-escape scan for text without a backslash - #762

Merged
nicholasserra merged 2 commits into
trentm:masterfrom
ptweezy:backslash-escape-guard
Nov 5, 2026
Merged

nicholasserra merged 2 commits into
trentm:masterfrom
ptweezy:backslash-escape-guard

Conversation

@ptweezy

@ptweezy ptweezy commented Nov 4, 2026

Copy link
Copy Markdown
Contributor

_encode_backslash_escapes() runs one str.replace() per _escape_table entry, and _protect_url() adds every link URL to that table. Documents with many links are quadratic.

Change

Every search string in the loop starts with a backslash. Return early when the text has none. Output is unchanged.

Timing

Median of 5 alternating rounds, a new Markdown() per call, identical output.

Links per document 250 1,000 4,000 8,000
Changelog (link per bullet) 1.4x 2.2x 5.9x 10.7x (2.39 → 0.22 s)
Inline link per paragraph 1.5x 2.7x 7.9x 15.1x (2.08 → 0.14 s)
Reference links 1.5x 2.7x 7.9x 15.1x (1.97 → 0.13 s)

No links: 1.1x. A backslash in every paragraph: 1.0x.

MacBook Air M4, macOS 27.2, Python 3.14.10.

Tests

  • python test.py -- -knownfailure: 304 pass (master: 303); ReDoS 12 of 12.
  • All 294 test cases, 6 option sets, plus a run with about 30 extras and reused instances: identical output.
  • New test: 1,000 links plus a paragraph with backslash escapes.

Related: #724 sped up the sibling _unescape_special_chars() (#635).

_encode_backslash_escapes() runs one replace() per _escape_table entry,
and every link URL is in that table, so link-heavy documents are
quadratic. Every search string starts with a backslash; return early
when the text has none.
@ptweezy
ptweezy force-pushed the backslash-escape-guard branch from d05e62f to d6188a5 Compare November 4, 2026 03:44
@nicholasserra

Copy link
Copy Markdown
Collaborator

Thanks!

@nicholasserra
nicholasserra merged commit 0ea342a into trentm:master Nov 5, 2026
15 checks passed
@ptweezy
ptweezy deleted the backslash-escape-guard branch November 5, 2026 03:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants