Skip to content

Include the namespace in the HTML fragment cache key - #618

Open
Shaisolaris wants to merge 1 commit into
PuerkitoBio:masterfrom
Shaisolaris:fragment-cache-namespace
Open

Shaisolaris wants to merge 1 commit into
PuerkitoBio:masterfrom
Shaisolaris:fragment-cache-namespace

Conversation

@Shaisolaris

Copy link
Copy Markdown

Description

cachedParseHtmlWithContext keys its cache on nodeName(context) (plus the form ancestor flag from #615), which drops the namespace. An HTML element and an SVG or MathML element with the same tag name therefore share one parse, and whichever is seen first decides the result for both.

This shows up with <title> and <style>, whose content is text in HTML but markup in foreign content:

doc, _ := goquery.NewDocumentFromReader(strings.NewReader(
	`<html><head><title>a</title></head><body><svg><title>b</title></svg></body></html>`))
doc.Find("title").AppendHtml(`<b>x</b>`)
// The SVG <title> gets the text "<b>x</b>" instead of a <b> element.
// With the elements in the other order, the HTML <title> gets a <b> element.

The fix adds context.Namespace to the cache key. Elements with the same name and namespace still share the cached parse.

Related Issue

None that I found. This is the same cache as #586 and #615.

How Has This Been Tested?

  • Added TestAppendHtmlNamespaceContext and TestSetHtmlNamespaceContext. Both fail on master and pass with this change.
  • go vet . and go test . pass locally with Go 1.25.0. I did not run the CI matrix.

cachedParseHtmlWithContext keyed parsed fragments by tag name only, so
an HTML element and an SVG or MathML element with the same name shared
one parse.  <title> and <style> parse their content as text in HTML but
as markup inside <svg>, so whichever was seen first decided the result
for both.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant