Skip to content

Commit

Permalink
fix: regression for astro attributes escaping (#10728)
Browse files Browse the repository at this point in the history
  • Loading branch information
ematipico committed Apr 9, 2024
1 parent b21b3ba commit f508c4b
Show file tree
Hide file tree
Showing 4 changed files with 18 additions and 5 deletions.
5 changes: 5 additions & 0 deletions .changeset/large-knives-confess.md
@@ -0,0 +1,5 @@
---
"astro": patch
---

Fixes a regression where some very **specific** code rendered using `expressive-code` was not escaped properly.
9 changes: 5 additions & 4 deletions packages/astro/src/runtime/server/render/util.ts
Expand Up @@ -105,7 +105,7 @@ Make sure to use the static attribute syntax (\`${key}={value}\`) instead of the
}

// Prevents URLs in attributes from being escaped in static builds
if (typeof value === 'string' && value.includes('&') && urlCanParse(value)) {
if (typeof value === 'string' && value.includes('&') && isHttpUrl(value)) {
return markHTMLString(` ${key}="${toAttributeString(value, false)}"`);
}

Expand Down Expand Up @@ -247,10 +247,11 @@ export function promiseWithResolvers<T = any>(): PromiseWithResolvers<T> {
};
}

function urlCanParse(url: string) {
const VALID_PROTOCOLS = ['http:', 'https:'];
function isHttpUrl(url: string) {
try {
new URL(url);
return true;
const parsedUrl = new URL(url);
return VALID_PROTOCOLS.includes(parsedUrl.protocol);
} catch {
return false;
}
Expand Down
6 changes: 6 additions & 0 deletions packages/astro/test/astro-attrs.test.js
Expand Up @@ -37,6 +37,12 @@ describe('Attributes', async () => {
true
);

// cheerio will unescape the values, so checking that the url rendered unescaped to begin with has to be done manually
assert.equal(
html.includes('cmd: echo &#34;foo&#34; &#38;&#38; echo &#34;bar&#34; > /tmp/hello.txt'),
true
);

for (const id of Object.keys(attrs)) {
const { attribute, value } = attrs[id];
const attr = $(`#${id}`).attr(attribute);
Expand Down
Expand Up @@ -6,6 +6,7 @@
<span id="null" attr={null} />
<span id="undefined" attr={undefined} />
<span id="url" attr={"https://example.com/api/og?title=hello&description=somedescription"}/>
<span id="code" attr={"cmd: echo \"foo\" && echo \"bar\" > /tmp/hello.txt"} />
<!--
Per HTML spec, some attributes should be treated as booleans
These should always render <span async /> or <span /> (without a string value)
Expand All @@ -19,4 +20,4 @@
-->
<span id='html-enum' draggable='true' />
<span id='html-enum-true' draggable={true} />
<span id='html-enum-false' draggable={false} />
<span id='html-enum-false' draggable={false} />

0 comments on commit f508c4b

Please sign in to comment.