Skip to content

Commit e12f0d3

Browse files
chuenchen309claude
andcommitted
fix: keep escaped backslashes in angle-bracket link destinations
_parse_angle_link_href listed "\\" in its reject set, so any backslash inside <...> made it return None and the whole link (or reference definition) silently degraded to literal text. The bare-destination branch in parse_link_href already consumes "\\" plus the next char, and parse_link unescapes the result, so the escape machinery was already in place and only this branch refused to feed it. Consume the escape as a unit like the sibling branch does; an unescaped "<", line ending, or NUL still terminates as before. Matches CommonMark, which allows escaped "<"/">" inside an angle-bracket destination. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 719107f commit e12f0d3

2 files changed

Lines changed: 12 additions & 1 deletion

File tree

src/mistune/helpers.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,10 @@ def _parse_angle_link_href(src: str, pos: int) -> Union[Tuple[str, int], Tuple[N
242242
c = src[pos]
243243
if c == ">":
244244
return src[start:pos], pos + 1
245-
if c in "<\\\n\r\x00":
245+
if c == "\\":
246+
pos = min(pos + 2, len(src))
247+
continue
248+
if c in "<\n\r\x00":
246249
return None, None
247250
pos += 1
248251
return None, None

tests/test_misc.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,14 @@ def test_link_bracket_cache_cases(self):
134134
for text, html in cases.items():
135135
self.assertEqual(mistune.html(text).strip(), html)
136136

137+
def test_angle_link_escaped_backslash(self):
138+
cases = {
139+
r"[link](<foo\*bar>)": '<p><a href="foo*bar">link</a></p>',
140+
"[x]: <a\\*b>\n\n[x]": '<p><a href="a*b">x</a></p>',
141+
}
142+
for text, html in cases.items():
143+
self.assertEqual(mistune.html(text).strip(), html, text)
144+
137145
def test_allow_harmful_protocols(self):
138146
renderer = mistune.HTMLRenderer(allow_harmful_protocols=True)
139147
md = mistune.Markdown(renderer)

0 commit comments

Comments
 (0)