Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions docs/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ See the [Contributing Guide](contributing.md) for details.
* Fix an issue with excessive backtracking when matching inline code blocks (#1617).
* `md_in_html` now honors tags added to `Markdown.block_level_elements` after
the extension is loaded (#1246).
* Fix quadratic-time regex backtracking in `ReferenceProcessor` when a link
reference definition has no URL, e.g. a line consisting only of `[id]:`
followed by many trailing spaces (#798).

## [3.10.3] - 2026-07-30

Expand Down
3 changes: 2 additions & 1 deletion markdown/blockprocessors.py
Original file line number Diff line number Diff line change
Expand Up @@ -577,7 +577,8 @@ def run(self, parent: etree.Element, blocks: list[str]) -> None:
class ReferenceProcessor(BlockProcessor):
""" Process link references. """
RE = re.compile(
r'^[ ]{0,3}\[([^\[\]]*)\]:[ ]*\n?[ ]*([^\s]+)[ ]*(?:\n[ ]*)?((["\'])(.*)\4[ ]*|\((.*)\)[ ]*)?$', re.MULTILINE
r'^[ ]{0,3}\[([^\[\]]*)\]:[ ]*(?:\n[ ]*)?([^\s]+)[ ]*(?:\n[ ]*)?((["\'])(.*)\4[ ]*|\((.*)\)[ ]*)?$',
re.MULTILINE
)

def test(self, parent: etree.Element, block: str) -> bool:
Expand Down
62 changes: 62 additions & 0 deletions tests/test_syntax/blocks/test_reference_links.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
"""
Python Markdown

A Python implementation of John Gruber's Markdown.

Documentation: https://python-markdown.github.io/
GitHub: https://github.com/Python-Markdown/markdown/
PyPI: https://pypi.org/project/Markdown/

Started by Manfred Stienstra (http://www.dwerg.net/).
Maintained for a few years by Yuri Takhteyev (http://www.freewisdom.org).
Currently maintained by Waylan Limberg (https://github.com/waylan),
Dmitry Shachnev (https://github.com/mitya57) and Isaac Muse (https://github.com/facelessuser).

Copyright 2007-2023 The Python Markdown Project (v. 1.7 and later)
Copyright 2004, 2005, 2006 Yuri Takhteyev (v. 0.2-1.6b)
Copyright 2004 Manfred Stienstra (the original version)

License: BSD (see LICENSE.md for details).
"""

from markdown.test_tools import TestCase


class TestReferenceLinks(TestCase):

def test_reference_link(self):
self.assertMarkdownRenders(
'[Text][id]\n\n[id]: http://example.com',
'<p><a href="http://example.com">Text</a></p>'
)

def test_reference_link_split_across_lines(self):
self.assertMarkdownRenders(
'[Text][id]\n\n[id]:\nhttp://example.com',
'<p><a href="http://example.com">Text</a></p>'
)

def test_reference_link_with_title(self):
self.assertMarkdownRenders(
'[Text][id]\n\n[id]: http://example.com "Title"',
'<p><a href="http://example.com" title="Title">Text</a></p>'
)

def test_reference_link_title_on_own_line(self):
self.assertMarkdownRenders(
'[Text][id]\n\n[id]: http://example.com\n"Title"',
'<p><a href="http://example.com" title="Title">Text</a></p>'
)

def test_malformed_reference_with_long_run_of_spaces(self):
"""
A reference definition whose URL is missing (only trailing spaces
after the colon) should still be treated as plain text, no matter
how many trailing spaces there are.

See https://github.com/Python-Markdown/markdown/issues/798
"""
text = '[id]:' + (' ' * 50000)
self.assertMarkdownRenders(
text, f'<p>{text}</p>', expected_attrs={'references': {}}
)