Skip to content
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion packages/vite/src/module-runner/evaluatedModules.ts
Original file line number Diff line number Diff line change
Expand Up @@ -108,8 +108,14 @@ export class EvaluatedModules {
if (!mod) return null
if (mod.map) return mod.map
if (!mod.meta || !('code' in mod.meta)) return null

// Find the last occurrence of sourceMappingURL by finding the last line that contains it
const pattern = `//# ${SOURCEMAPPING_URL}=data:application/json;base64,`
const lastIndex = mod.meta.code.lastIndexOf(pattern)
if (lastIndex === -1) return null

const mapString = MODULE_RUNNER_SOURCEMAPPING_REGEXP.exec(
mod.meta.code,
mod.meta.code.slice(lastIndex),
)?.[1]
if (!mapString) return null
mod.map = new DecodedMap(JSON.parse(decodeBase64(mapString)), mod.file)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,4 +93,24 @@ describe('module runner initialization', async () => {
' at Module.main (<root>/fixtures/has-error-deep.ts:6:3)',
])
})

it('should not crash when sourceMappingURL pattern appears in string literals', async ({
runner,
}) => {
const modules = runner.evaluatedModules

const moduleId = '/test/string-literal-sourcemap.js'
const moduleUrl = 'http://localhost:3000/test/string-literal-sourcemap.js'
const node = modules.ensureModule(moduleId, moduleUrl)

node.meta = {
code: `const text = "//# sourceMappingURL=data:application/json;base64,invalidbase64";
console.log(text);`,
}

expect(() => {
const sourceMap = modules.getModuleSourceMapById(moduleId)
expect(sourceMap).toBeNull()
}).not.toThrow()
})
})
Loading