mirror of
https://github.com/vercel-labs/scriptc.git
synced 2026-10-29 07:04:09 +08:00
scr_regex_replace_callback freed its output buffer with free() when the replacer threw after an earlier match had been written, but the buffer is the body of a runtime string, so the process aborted with "free(): invalid pointer" instead of propagating the exception. It now abandons the buffer through scr_jb_abandon, which releases the string. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
27 lines
842 B
TypeScript
27 lines
842 B
TypeScript
// A replace callback that throws after earlier matches were replaced: the
|
|
// partial result is discarded and the exception propagates, with the
|
|
// callbacks that ran counted exactly as in Node.
|
|
let calls = 0;
|
|
function replacer(m: string, digit?: string): string {
|
|
calls++;
|
|
if (digit === "3") throw new RangeError("stop at " + m);
|
|
return "<" + m + ">";
|
|
}
|
|
for (const subject of ["a1b2c3d4", "x3", "no digits"]) {
|
|
calls = 0;
|
|
try {
|
|
console.log(subject.replace(/(\d)|z/g, replacer), calls);
|
|
} catch (error) {
|
|
console.log(error instanceof RangeError, (error as Error).message, calls);
|
|
}
|
|
}
|
|
const parts: string[] = [];
|
|
for (let i = 0; i < 50; i++) {
|
|
try {
|
|
parts.push(("k" + i + "-3").replace(/(\d)/g, replacer));
|
|
} catch {
|
|
parts.push("thrown");
|
|
}
|
|
}
|
|
console.log(parts.filter((p) => p === "thrown").length, calls);
|