-
-
Notifications
You must be signed in to change notification settings - Fork 7.5k
fix(module-runner): prevent crash when sourceMappingURL pattern appears in string literals #20554
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
sapphi-red
merged 14 commits into
main
from
copilot/fix-f6dcea62-4f8d-4abb-8a91-7f1398805346
Aug 8, 2025
Merged
Changes from 3 commits
Commits
Show all changes
14 commits
Select commit
Hold shift + click to select a range
1cad4a7
Initial plan
Copilot 5de6472
Fix MODULE_RUNNER_SOURCEMAPPING_REGEXP to find last occurrence and av…
Copilot 38afca3
Complete fix for issue #20551 with comprehensive tests
Copilot 545f586
Address review feedback: revert regex pattern, hoist regex, use lastI…
Copilot e3a280c
Address review feedback: simplify mapString extraction and remove obv…
Copilot c94ab91
revert try-catch block to original format as requested
Copilot 2e3126c
update
sapphi-red 9058401
chore: update
sapphi-red 76e0cff
fix: address review feedback - remove empty line, simplify return sta…
Copilot 67b5890
update
sapphi-red 45ed63a
fix: address review feedback - remove console.log, add throwError fun…
Copilot 29177ba
chore: update
sapphi-red 7695ec6
Address review feedback: remove empty line and add stacktrace verific…
Copilot 22c56ce
chore: update
sapphi-red File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
90 changes: 90 additions & 0 deletions
90
packages/vite/src/module-runner/__tests__/evaluatedModules.spec.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,90 @@ | ||
| import { describe, expect, it } from 'vitest' | ||
| import { EvaluatedModules } from '../evaluatedModules' | ||
|
|
||
| describe('EvaluatedModules sourcemap extraction', () => { | ||
| it('should not crash with InvalidCharacterError when string literals contain sourceMappingURL pattern', () => { | ||
| const modules = new EvaluatedModules() | ||
|
|
||
| // Create a module with source mapping URL in string literal - this is the exact scenario from the issue | ||
| const moduleId = '/test/module.js' | ||
| const moduleUrl = 'http://localhost:3000/test/module.js' | ||
| const node = modules.ensureModule(moduleId, moduleUrl) | ||
|
|
||
| // This is the exact problematic code pattern mentioned in the GitHub issue | ||
| node.meta = { | ||
| code: `throw lazyDOMException('Invalid character', 'InvalidCharacterError'); | ||
| ^ | ||
| DOMException [InvalidCharacterError]: Invalid character | ||
| at atob (node:buffer:1302:13) | ||
| at EvaluatedModules.getModuleSourceMapById (file:///Users/ari/Git/repros/module-runner/node_modules/.pnpm/[email protected]/node_modules/vite/dist/node/module-runner.js:286:59) | ||
| at file:///Users/ari/Git/repros/module-runner/index.mjs:24:31 | ||
|
|
||
| const text = "//# sourceMappingURL=data:application/json;base64,\${encoded}";`, | ||
| } | ||
|
|
||
| // Before the fix: This would throw InvalidCharacterError: Invalid character | ||
| // After the fix: This should not crash and should return null gracefully | ||
| expect(() => { | ||
| const sourceMap = modules.getModuleSourceMapById(moduleId) | ||
| // The result should be null since there's no valid sourcemap, but it shouldn't crash | ||
| expect(sourceMap).toBeNull() | ||
| }).not.toThrow('Invalid character') | ||
| }) | ||
|
|
||
| it('should correctly extract valid sourcemap when present at end of file', () => { | ||
| const modules = new EvaluatedModules() | ||
|
|
||
| const moduleId = '/test/valid-module.js' | ||
| const moduleUrl = 'http://localhost:3000/test/valid-module.js' | ||
| const node = modules.ensureModule(moduleId, moduleUrl) | ||
|
|
||
| // Code with string literal AND a valid sourcemap at the end | ||
| node.meta = { | ||
| code: `function example() { | ||
| const text = "//# sourceMappingURL=data:application/json;base64,invalidbase64"; | ||
| return text; | ||
| } | ||
|
|
||
| //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGVzdC5qcyIsInNvdXJjZXMiOlsidGVzdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSJ9`, | ||
| } | ||
|
|
||
| const sourceMap = modules.getModuleSourceMapById(moduleId) | ||
| expect(sourceMap).toBeTruthy() | ||
| expect(sourceMap?.map.version).toBe(3) | ||
| expect(sourceMap?.map.file).toBe('test.js') | ||
| }) | ||
|
|
||
| it('should return null if no valid sourcemap is found', () => { | ||
| const modules = new EvaluatedModules() | ||
|
|
||
| const moduleId = '/test/module2.js' | ||
| const moduleUrl = 'http://localhost:3000/test/module2.js' | ||
| const node = modules.ensureModule(moduleId, moduleUrl) | ||
|
|
||
| node.meta = { | ||
| code: `function example() { return "no sourcemap here"; }`, | ||
| } | ||
|
|
||
| const sourceMap = modules.getModuleSourceMapById(moduleId) | ||
| expect(sourceMap).toBeNull() | ||
| }) | ||
|
|
||
| it('should handle invalid base64 gracefully without crashing', () => { | ||
| const modules = new EvaluatedModules() | ||
|
|
||
| const moduleId = '/test/module3.js' | ||
| const moduleUrl = 'http://localhost:3000/test/module3.js' | ||
| const node = modules.ensureModule(moduleId, moduleUrl) | ||
|
|
||
| node.meta = { | ||
| code: `function example() { return "test"; } | ||
| //# sourceMappingURL=data:application/json;base64,invalidbase64`, | ||
| } | ||
|
|
||
| // This should handle the invalid base64 gracefully and not crash | ||
| expect(() => { | ||
| const sourceMap = modules.getModuleSourceMapById(moduleId) | ||
| expect(sourceMap).toBeNull() | ||
| }).not.toThrow() | ||
| }) | ||
| }) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.