markup/goldmark: Fix double-escaping of ampersands in link URLs

The XSS fix in 479fe6c65 accidentally called util.EscapeHTML twice
on link destinations, causing `&` to render as `&` instead
of `&`.

Fixes #14715

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Bjørn Erik Pedersen
2026-04-03 22:03:19 +02:00
parent 481baa0896
commit dc9b51d2e2
2 changed files with 22 additions and 1 deletions
@@ -1047,3 +1047,24 @@ Content: {{ .Content }}
`! alert(2)"`,
)
}
// Issue 14715
func TestRenderLinkDefaultAmpersand(t *testing.T) {
t.Parallel()
files := `
-- content/_index.md --
---
title: "Home"
---
[foo](https://a.com/?a=1&b=2)
-- layouts/home.html --
{{ .Content }}
`
b := hugolib.Test(t, files)
b.AssertFileContent("public/index.html",
`<a href="https://a.com/?a=1&amp;b=2">foo</a>`,
)
}
+1 -1
View File
@@ -349,7 +349,7 @@ func (r *hookedRenderer) renderLinkDefault(w util.BufWriter, source []byte, node
_, _ = w.WriteString("<a href=\"")
dest := util.URLEscape(n.Destination, true)
if r.Unsafe || !html.IsDangerousURL(dest) {
_, _ = w.Write(util.EscapeHTML(util.EscapeHTML(dest)))
_, _ = w.Write(util.EscapeHTML(dest))
}
_ = w.WriteByte('"')
if n.Title != nil {