diff --git a/.changeset/fresh-baboons-switch.md b/.changeset/fresh-baboons-switch.md new file mode 100644 index 0000000000..3d5a686f55 --- /dev/null +++ b/.changeset/fresh-baboons-switch.md @@ -0,0 +1,5 @@ +--- +'astro': patch +--- + +Escape closing script tag with `define:vars` diff --git a/packages/astro/src/runtime/server/render/util.ts b/packages/astro/src/runtime/server/render/util.ts index cb96da29f0..fcf9ee7226 100644 --- a/packages/astro/src/runtime/server/render/util.ts +++ b/packages/astro/src/runtime/server/render/util.ts @@ -43,7 +43,7 @@ export function defineScriptVars(vars: Record) { for (const [key, value] of Object.entries(vars)) { // Use const instead of let as let global unsupported with Safari // https://stackoverflow.com/questions/29194024/cant-use-let-keyword-in-safari-javascript - output += `const ${toIdent(key)} = ${JSON.stringify(value)};\n`; + output += `const ${toIdent(key)} = ${JSON.stringify(value).replace(/<\/script>/g, "\\x3C/script>")};\n`; } return markHTMLString(output); } diff --git a/packages/astro/test/astro-directives.test.js b/packages/astro/test/astro-directives.test.js index 7f47ff60f8..c4098b4fe6 100644 --- a/packages/astro/test/astro-directives.test.js +++ b/packages/astro/test/astro-directives.test.js @@ -14,7 +14,7 @@ describe('Directives', async () => { const html = await fixture.readFile('/define-vars/index.html'); const $ = cheerio.load(html); - expect($('script')).to.have.lengthOf(3); + expect($('script')).to.have.lengthOf(4); let i = 0; for (const script of $('script').toArray()) { @@ -24,9 +24,12 @@ describe('Directives', async () => { if (i < 2) { // Inline defined variables expect($(script).toString()).to.include('const foo = "bar"'); - } else { + } else if (i < 3) { // Convert invalid keys to valid identifiers expect($(script).toString()).to.include('const dashCase = "bar"'); + } else { + // Closing script tags in strings are escaped + expect($(script).toString()).to.include('const bar = "' --- @@ -28,6 +29,9 @@ let fg = 'black' + </body>