-
-
Notifications
You must be signed in to change notification settings - Fork 3.5k
Inconsistent HTML escaping of & in head — & in attributes vs & in text nodes #16657
Copy link
Copy link
Closed
Labels
- P2: nice to haveNot breaking anything but nice to have (priority)Not breaking anything but nice to have (priority)- P3: minor bugAn edge case that only affects very specific usage (priority)An edge case that only affects very specific usage (priority)feat: renderingRelated to prop serialization, html escaping, and framework components (scope)Related to prop serialization, html escaping, and framework components (scope)pkg: astroRelated to the core `astro` package (scope)Related to the core `astro` package (scope)
Metadata
Metadata
Assignees
Labels
- P2: nice to haveNot breaking anything but nice to have (priority)Not breaking anything but nice to have (priority)- P3: minor bugAn edge case that only affects very specific usage (priority)An edge case that only affects very specific usage (priority)feat: renderingRelated to prop serialization, html escaping, and framework components (scope)Related to prop serialization, html escaping, and framework components (scope)pkg: astroRelated to the core `astro` package (scope)Related to the core `astro` package (scope)
Type
Fields
Give feedbackNo fields configured for issues without a type.
Astro Info
If this issue only occurs in one browser, which browser is a problem?
All browsers
Describe the Bug
When rendering HTML
<head>elements, the&character is escaped inconsistently depending on where it appears:<title>{title}</title>),&is escaped to&via thehtml-escaperlibrary (escapeHTML).<meta name="..." content={title} />),&is escaped to&via the internaltoAttributeString()function inpackages/astro/src/runtime/server/render/util.ts.Both
&and&are equivalent per the HTML spec, but mixing them produces inconsistent raw HTML output. This is visible when inspecting the page source or fetching it viacurl -sL.Root cause:
The
toAttributeStringfunction uses a manual regex replacement (&→&,"→") instead of delegating to the sameescapeHTMLfunction used for text nodes.What's the expected result?
The
&character should be consistently escaped as&across both text nodes and attribute values in the rendered HTML output.Suggested fix in
packages/astro/src/runtime/server/render/util.ts:Link to Minimal Reproducible Example
&to both<title>{title}</title>and<meta content={title} />.curl -sL http://localhost:4321and inspect the<head>output.<title>contains&while<meta content>contains&.Participation