Skip to content

Fix excessive backtracking when matching inline code blocks - #1618

Merged
waylan merged 1 commit into
Python-Markdown:masterfrom
facelessuser:bugfix/backtrack-backtick
Aug 8, 2026
Merged

Fix excessive backtracking when matching inline code blocks#1618
waylan merged 1 commit into
Python-Markdown:masterfrom
facelessuser:bugfix/backtrack-backtick

Conversation

@facelessuser

Copy link
Copy Markdown
Collaborator

Fixes #1617

Description

AI Assistance Disclosure

  • No AI tools were used in preparing this PR.
  • If AI tools were used, I have disclosed which ones, and fully reviewed and verified their output.

Checklist

  • This PR follows the contribution guidelines.
  • The code follows the Code Style Guide.
  • The commit message follows the Commit Message Style Guide.
  • I have added or updated relevant docs, including release notes if applicable which follow the [Documentation Style Guide](Documentation Style Guide).
  • I have added or updated relevant tests.
  • I have not requested, and will not request, an automated AI review for this PR.

@waylan waylan left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me. Curious if you checked how this affects performance.

@facelessuser

Copy link
Copy Markdown
Collaborator Author

I only ran it through the test script submitted in the issue. It at least resolved performance there. But we could do more tests if there is interest.

@waylan
waylan merged commit 7be0cff into Python-Markdown:master Aug 8, 2026
15 checks passed
@facelessuser

Copy link
Copy Markdown
Collaborator Author

As far as performance. If we care, we could make it a little faster by removing the RE_TICKS usage and just iterating over the string. As this is already merged, that would need a separate PR. I won't worry about it unless this is requested, but figured I'd note it here.

diff --git a/markdown/inlinepatterns.py b/markdown/inlinepatterns.py
index 1a79bc4..0d8801a 100644
--- a/markdown/inlinepatterns.py
+++ b/markdown/inlinepatterns.py
@@ -447,29 +447,34 @@ class BacktickInlineProcessor(InlineProcessor):
     def find_code_spans(self, start: int, text: str) -> tuple[int, int] | None:
         """Find code spans."""
 
+        last = len(text)
+
         # Get the maximum starting ticks
-        m = self.RE_TICKS.match(text, start)
-        if m is None:  # pragma: no cover
+        max_ticks = 0
+        while start < last and text[start] == '`':
+            max_ticks += 1
+            start += 1
+
+        if not max_ticks:  # pragma: no cover
             # This is not ever expected to happen.
             return None
-        max_ticks = len(m.group(0))
 
-        start = m.end(0)
-        last = len(text)
         longest_span = 0
         end = 0
 
         # Find an ending span of backticks that matches our opening
         i = start
         while i < last:
-            m = self.RE_TICKS.match(text, i)
-            if m is None:
+            span_length = 0
+            while i < last and text[i] == '`':
+                span_length += 1
+                i += 1
+                continue
+            if not span_length:
                 i += 1
                 continue
 
             # Did we find the end?
-            i = m.end(0)
-            span_length = len(m.group(0))
             if max_ticks == span_length:
                 return start, i - span_length
 
@waylan

waylan commented Aug 10, 2026

Copy link
Copy Markdown
Member

As you already did the work, might as well use it. Feel free to open a new PR.

Thanks

waylan pushed a commit that referenced this pull request Aug 30, 2026
Same behavior as the current finder, just a linear scan. Sketch is from
Isaac in #1618.

Fixes #1620.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

2 participants