From d220edd75439fde00a60145b78ba7cc6d707f210 Mon Sep 17 00:00:00 2001 From: Dominic Gannaway Date: Thu, 10 Oct 2024 14:32:56 +0100 Subject: [PATCH] fix: strip BOM character from beginning of input (#13548) Fixes #13519 --------- Co-authored-by: Simon Holthausen --- .changeset/twelve-mayflies-decide.md | 5 +++++ packages/svelte/src/compiler/index.js | 14 +++++++++++++ packages/svelte/tests/parser-modern/test.ts | 23 ++++++++++++++++++++- 3 files changed, 41 insertions(+), 1 deletion(-) create mode 100644 .changeset/twelve-mayflies-decide.md diff --git a/.changeset/twelve-mayflies-decide.md b/.changeset/twelve-mayflies-decide.md new file mode 100644 index 0000000000..01d72c46bd --- /dev/null +++ b/.changeset/twelve-mayflies-decide.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +fix: strip BOM character from input diff --git a/packages/svelte/src/compiler/index.js b/packages/svelte/src/compiler/index.js index 5eb22bcd0a..2b3ad99d8b 100644 --- a/packages/svelte/src/compiler/index.js +++ b/packages/svelte/src/compiler/index.js @@ -20,6 +20,7 @@ export { default as preprocess } from './preprocess/index.js'; * @returns {CompileResult} */ export function compile(source, options) { + source = remove_bom(source); state.reset_warning_filter(options.warningFilter); const validated = validate_component_options(options, ''); state.reset(source, validated); @@ -58,6 +59,7 @@ export function compile(source, options) { * @returns {CompileResult} */ export function compileModule(source, options) { + source = remove_bom(source); state.reset_warning_filter(options.warningFilter); const validated = validate_module_options(options, ''); state.reset(source, validated); @@ -101,6 +103,7 @@ export function compileModule(source, options) { * @returns {AST.Root | LegacyRoot} */ export function parse(source, { filename, rootDir, modern } = {}) { + source = remove_bom(source); state.reset_warning_filter(() => false); state.reset(source, { filename: filename ?? '(unknown)', rootDir }); @@ -140,6 +143,17 @@ function to_public_ast(source, ast, modern) { return convert(source, ast); } +/** + * Remove the byte order mark from a string if it's present since it would mess with our template generation logic + * @param {string} source + */ +function remove_bom(source) { + if (source.charCodeAt(0) === 0xfeff) { + return source.slice(1); + } + return source; +} + /** * @deprecated Replace this with `import { walk } from 'estree-walker'` * @returns {never} diff --git a/packages/svelte/tests/parser-modern/test.ts b/packages/svelte/tests/parser-modern/test.ts index 7576bddfe4..04af8b0780 100644 --- a/packages/svelte/tests/parser-modern/test.ts +++ b/packages/svelte/tests/parser-modern/test.ts @@ -1,5 +1,5 @@ import * as fs from 'node:fs'; -import { assert } from 'vitest'; +import { assert, it } from 'vitest'; import { parse } from 'svelte/compiler'; import { try_load_json } from '../helpers.js'; import { suite, type BaseTest } from '../suite.js'; @@ -34,3 +34,24 @@ const { test, run } = suite(async (config, cwd) => { export { test }; await run(__dirname); + +it('Strips BOM from the input', () => { + const input = '\uFEFF
'; + const actual = parse(input, { modern: true }); + assert.deepEqual(JSON.parse(JSON.stringify(actual.fragment)), { + type: 'Fragment', + nodes: [ + { + attributes: [], + end: 11, + fragment: { + nodes: [], + type: 'Fragment' + }, + name: 'div', + start: 0, + type: 'RegularElement' + } + ] + }); +});