Skip to content

Commit 53e6b63

Browse files
Lms24cursoragent
andauthored
fix(core): Wrap decodeURI in node stack trace parser to handle malformed URIs (#19400)
This PR wraps `decodeURI` in `node-stack-trace.ts` with a try/catch so that malformed URIs (e.g. filenames containing `%` sequences that are not valid percent-encoding) no longer throw a `URIError` and crash the SDK. The raw filename is returned as a fallback. In addition, we only call `getModule` if we successfully decode the filename, since in `getModule` implementations, we also again attempt to decode filenames. Since we don't have a concrete filename in #19391 which we can reproduce this, this is rather a "best effort" fix. But I think it's worth having this either way. Closes #19391 --------- Co-authored-by: Cursor <cursoragent@cursor.com>
1 parent 4bb5e03 commit 53e6b63

File tree

2 files changed

+28
-2
lines changed

2 files changed

+28
-2
lines changed

packages/core/src/utils/node-stack-trace.ts

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,9 +115,10 @@ export function node(getModule?: GetModuleFn): StackLineParserFn {
115115
filename = lineMatch[5];
116116
}
117117

118+
const maybeDecodedFilename = filename ? _safeDecodeURI(filename) : undefined;
118119
return {
119-
filename: filename ? decodeURI(filename) : undefined,
120-
module: getModule ? getModule(filename) : undefined,
120+
filename: maybeDecodedFilename ?? filename,
121+
module: maybeDecodedFilename && getModule?.(maybeDecodedFilename),
121122
function: functionName,
122123
lineno: _parseIntOrUndefined(lineMatch[3]),
123124
colno: _parseIntOrUndefined(lineMatch[4]),
@@ -148,3 +149,11 @@ export function nodeStackLineParser(getModule?: GetModuleFn): StackLineParser {
148149
function _parseIntOrUndefined(input: string | undefined): number | undefined {
149150
return parseInt(input || '', 10) || undefined;
150151
}
152+
153+
function _safeDecodeURI(filename: string): string | undefined {
154+
try {
155+
return decodeURI(filename);
156+
} catch {
157+
return undefined;
158+
}
159+
}

packages/core/test/lib/utils/stacktrace.test.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -392,4 +392,21 @@ describe('node', () => {
392392

393393
expect(node(input)).toEqual(expectedOutput);
394394
});
395+
396+
it('returns the raw filename when decodeURI throws a URIError', () => {
397+
const malformedFilename = '/path/to/%file%.js';
398+
const input = `at myFunction (${malformedFilename}:10:5)`;
399+
400+
const result = node(input);
401+
402+
expect(result?.filename).toBe('/path/to/%file%.js');
403+
});
404+
405+
it('decodes a valid percent-encoded filename', () => {
406+
const input = 'at myFunction (/path/to/my%20file.js:10:5)';
407+
408+
const result = node(input);
409+
410+
expect(result?.filename).toBe('/path/to/my file.js');
411+
});
395412
});

0 commit comments

Comments
 (0)