fix(javascript): handle oversized inline source maps (#1386)

* fix(javascript): handle oversized inline source maps

* fix(javascript): avoid source map directive regex overflow
This commit is contained in:
Minghang Chamling
2026-10-10 10:24:38 +08:00
committed by GitHub
parent 7aa4d768eb
commit 5fc4d792ca
2 changed files with 80 additions and 7 deletions
@@ -306,13 +306,32 @@ export const addSourceMapDirectives = (
end === null
)
continue;
const match = /^(?:\/\/|\/\*)[#@]\s*sourceMappingURL\s*=\s*([^\s*]+)/u.exec(
source.slice(start, end),
);
if (match === null) continue;
const declared = match[1];
if (declared === undefined || declared.length === 0) continue;
const location = rangeForOffsets(source, start, start + match[0].length);
const commentSource = source.slice(start, end);
if (
!(commentSource.startsWith("//") || commentSource.startsWith("/*")) ||
!(commentSource[2] === "#" || commentSource[2] === "@")
)
continue;
// Single-class searches avoid regex backtracking over unbounded whitespace
// or inline URLs, which can exhaust the engine stack on two-byte strings.
const nameOffset = commentSource.slice(3).search(/\S/u);
if (nameOffset === -1) continue;
const nameStart = 3 + nameOffset;
if (!commentSource.startsWith("sourceMappingURL", nameStart)) continue;
const nameEnd = nameStart + "sourceMappingURL".length;
const equalsOffset = commentSource.slice(nameEnd).search(/\S/u);
if (equalsOffset === -1) continue;
const equalsStart = nameEnd + equalsOffset;
if (!commentSource.startsWith("=", equalsStart)) continue;
const urlOffset = commentSource.slice(equalsStart + 1).search(/\S/u);
if (urlOffset === -1) continue;
const declaredStart = equalsStart + 1 + urlOffset;
const terminator = commentSource.slice(declaredStart).search(/[\s*]/u);
const declaredEnd =
terminator === -1 ? commentSource.length : declaredStart + terminator;
if (declaredEnd === declaredStart) continue;
const declared = commentSource.slice(declaredStart, declaredEnd);
const location = rangeForOffsets(source, start, start + declaredEnd);
addFindingOnce(accumulator, `source-map\0${declared}`, () =>
accumulator.sourceMaps.push({ declared_url: declared, location }),
);