Skip to content

Commit c901e06

Browse files
vnykmshrkjk
authored andcommitted
fix: replace invalid codepoints with U+FFFD in entity parser
entity() emits a literal null byte for � instead of the Unicode replacement character. The CommonMark spec (section 6.2) requires U+FFFD for codepoint 0, surrogates (0xD800-0xDFFF), and values above 0x10FFFF. Check for all three invalid codepoint categories before converting to a rune.
1 parent a0dc97a commit c901e06

2 files changed

Lines changed: 14 additions & 1 deletion

File tree

inline_test.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1333,3 +1333,11 @@ func BenchmarkSmartDoubleQuotes(b *testing.B) {
13331333
runMarkdown("this should be normal \"quoted\" text.\n", params)
13341334
}
13351335
}
1336+
1337+
func TestEntityNullByte(t *testing.T) {
1338+
// � should produce U+FFFD per CommonMark spec section 6.2
1339+
doTestsInlineParam(t, []string{
1340+
"�",
1341+
"<p>\uFFFD</p>\n",
1342+
}, TestParams{})
1343+
}

parser/inline.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -817,7 +817,12 @@ func entity(p *Parser, data []byte, offset int) (int, ast.Node) {
817817
codepoint, err = strconv.ParseUint(string(ent[2:len(ent)-1]), 10, 64)
818818
}
819819
if err == nil { // only if conversion was valid return here.
820-
return end, newTextNode([]byte(string(rune(codepoint))))
820+
r := rune(codepoint)
821+
// Replace invalid codepoints with U+FFFD per CommonMark spec section 6.2
822+
if r == 0 || (r >= 0xD800 && r <= 0xDFFF) || r > 0x10FFFF {
823+
r = '\uFFFD'
824+
}
825+
return end, newTextNode([]byte(string(r)))
821826
}
822827

823828
return end, newTextNode(ent)

0 commit comments

Comments
 (0)