From 9c9bf4e7bdb73b6d21e27433fdbcc12680ed7e56 Mon Sep 17 00:00:00 2001 From: Alex Date: Thu, 25 Jan 2024 18:35:09 +1300 Subject: [PATCH 1/7] prevent URLs in `content` attributes being escapedk --- .changeset/quick-islands-ring.md | 5 +++++ packages/astro/src/runtime/server/render/util.ts | 5 +++++ 2 files changed, 10 insertions(+) create mode 100644 .changeset/quick-islands-ring.md diff --git a/.changeset/quick-islands-ring.md b/.changeset/quick-islands-ring.md new file mode 100644 index 000000000000..02baaf3952b5 --- /dev/null +++ b/.changeset/quick-islands-ring.md @@ -0,0 +1,5 @@ +--- +"astro": patch +--- + +Prevent URLs in `content` attributes being escaped for multiple params to work diff --git a/packages/astro/src/runtime/server/render/util.ts b/packages/astro/src/runtime/server/render/util.ts index 3fa01aeb616e..7ac3b8051792 100644 --- a/packages/astro/src/runtime/server/render/util.ts +++ b/packages/astro/src/runtime/server/render/util.ts @@ -104,6 +104,11 @@ Make sure to use the static attribute syntax (\`${key}={value}\`) instead of the return markHTMLString(` class="${toAttributeString(value, shouldEscape)}"`); } + // prevent URLs in `content` attributes being escaped for multiple params to work + if (key === 'content' && typeof value === 'string' && URL.canParse(value)) { + return markHTMLString(` ${key}="${toAttributeString(value, false)}"`); + } + // Boolean values only need the key if (value === true && (key.startsWith('data-') || htmlBooleanAttributes.test(key))) { return markHTMLString(` ${key}`); From 917addde460348aa8c506282074d4248de55e945 Mon Sep 17 00:00:00 2001 From: Alex Date: Fri, 26 Jan 2024 08:00:21 +1300 Subject: [PATCH 2/7] removed content check --- packages/astro/src/runtime/server/render/util.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/astro/src/runtime/server/render/util.ts b/packages/astro/src/runtime/server/render/util.ts index 7ac3b8051792..911188f33026 100644 --- a/packages/astro/src/runtime/server/render/util.ts +++ b/packages/astro/src/runtime/server/render/util.ts @@ -104,8 +104,8 @@ Make sure to use the static attribute syntax (\`${key}={value}\`) instead of the return markHTMLString(` class="${toAttributeString(value, shouldEscape)}"`); } - // prevent URLs in `content` attributes being escaped for multiple params to work - if (key === 'content' && typeof value === 'string' && URL.canParse(value)) { + // Prevents URLs in attributes from being escaped in static builds + if (typeof value === 'string' && URL.canParse(value)) { return markHTMLString(` ${key}="${toAttributeString(value, false)}"`); } From ff3286cd813b71e89a22bd28f49061e17c0f06c7 Mon Sep 17 00:00:00 2001 From: Alex Nguyen Date: Fri, 26 Jan 2024 08:00:58 +1300 Subject: [PATCH 3/7] Update .changeset/quick-islands-ring.md Co-authored-by: Florian Lefebvre --- .changeset/quick-islands-ring.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/quick-islands-ring.md b/.changeset/quick-islands-ring.md index 02baaf3952b5..5332107beb99 100644 --- a/.changeset/quick-islands-ring.md +++ b/.changeset/quick-islands-ring.md @@ -2,4 +2,4 @@ "astro": patch --- -Prevent URLs in `content` attributes being escaped for multiple params to work +Prevents URLs in attributes from being escaped in static builds From da6c8aa66a2ba4b6a74d96295766cf057ca5f437 Mon Sep 17 00:00:00 2001 From: Alex Date: Sat, 27 Jan 2024 06:54:03 +1300 Subject: [PATCH 4/7] add check for '&' in string --- packages/astro/src/runtime/server/render/util.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/astro/src/runtime/server/render/util.ts b/packages/astro/src/runtime/server/render/util.ts index 911188f33026..4d1568ff1f3b 100644 --- a/packages/astro/src/runtime/server/render/util.ts +++ b/packages/astro/src/runtime/server/render/util.ts @@ -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' && URL.canParse(value)) { + if (typeof value === 'string' && value.includes('&') && URL.canParse(value)) { return markHTMLString(` ${key}="${toAttributeString(value, false)}"`); } From 2746a5c4f97f78713f402f5e4d85001568049f95 Mon Sep 17 00:00:00 2001 From: Nate Moore Date: Tue, 13 Feb 2024 11:01:54 -0600 Subject: [PATCH 5/7] Update .changeset/quick-islands-ring.md --- .changeset/quick-islands-ring.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/quick-islands-ring.md b/.changeset/quick-islands-ring.md index 5332107beb99..a3b3e14ca04b 100644 --- a/.changeset/quick-islands-ring.md +++ b/.changeset/quick-islands-ring.md @@ -2,4 +2,4 @@ "astro": patch --- -Prevents URLs in attributes from being escaped in static builds +Prevents fully formed URLs in attributes from being escaped From bf4db624b7e4332e481002b9e96794771dfa0e13 Mon Sep 17 00:00:00 2001 From: lilnasy <69170106+lilnasy@users.noreply.github.com> Date: Fri, 8 Mar 2024 23:49:19 +0000 Subject: [PATCH 6/7] manual `canParse` --- packages/astro/src/runtime/server/render/util.ts | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/packages/astro/src/runtime/server/render/util.ts b/packages/astro/src/runtime/server/render/util.ts index 4d1568ff1f3b..52149a0319f2 100644 --- a/packages/astro/src/runtime/server/render/util.ts +++ b/packages/astro/src/runtime/server/render/util.ts @@ -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('&') && URL.canParse(value)) { + if (typeof value === 'string' && value.includes('&') && urlCanParse(value)) { return markHTMLString(` ${key}="${toAttributeString(value, false)}"`); } @@ -229,3 +229,12 @@ export function promiseWithResolvers(): PromiseWithResolvers { reject, }; } + +function urlCanParse(url: string) { + try { + new URL(url); + return true; + } catch { + return false; + } +} From 24bbb620069995e27d34faef062bcd2e4a8ca9e0 Mon Sep 17 00:00:00 2001 From: lilnasy <69170106+lilnasy@users.noreply.github.com> Date: Fri, 8 Mar 2024 23:49:28 +0000 Subject: [PATCH 7/7] add test --- packages/astro/test/astro-attrs.test.js | 3 +++ packages/astro/test/fixtures/astro-attrs/src/pages/index.astro | 1 + 2 files changed, 4 insertions(+) diff --git a/packages/astro/test/astro-attrs.test.js b/packages/astro/test/astro-attrs.test.js index 0866e4828ba3..4ee547d91d56 100644 --- a/packages/astro/test/astro-attrs.test.js +++ b/packages/astro/test/astro-attrs.test.js @@ -31,6 +31,9 @@ describe('Attributes', async () => { 'html-enum-false': { attribute: 'draggable', value: 'false' }, }; + // cheerio will unescape the values, so checking that the url rendered unescaped to begin with has to be done manually + assert.equal(html.includes("https://example.com/api/og?title=hello&description=somedescription"), true); + for (const id of Object.keys(attrs)) { const { attribute, value } = attrs[id]; const attr = $(`#${id}`).attr(attribute); diff --git a/packages/astro/test/fixtures/astro-attrs/src/pages/index.astro b/packages/astro/test/fixtures/astro-attrs/src/pages/index.astro index 82e03a3ae4e4..b7e617e365d2 100644 --- a/packages/astro/test/fixtures/astro-attrs/src/pages/index.astro +++ b/packages/astro/test/fixtures/astro-attrs/src/pages/index.astro @@ -5,6 +5,7 @@ +