From 8ecbb381ba3a3d7addd807f3d7c807ea45c02ad7 Mon Sep 17 00:00:00 2001 From: Steven Hugg Date: Thu, 17 Sep 2026 22:01:22 +0200 Subject: [PATCH] fixed some more "too much recursion" regexes --- src/worker/builder.ts | 26 ++++++++++++++++++-------- src/worker/tools/mcpp.ts | 4 +++- 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/src/worker/builder.ts b/src/worker/builder.ts index 85693b0b..aa5f0585 100644 --- a/src/worker/builder.ts +++ b/src/worker/builder.ts @@ -614,9 +614,13 @@ function setLinkSymbol(params, symbols: PhaseLists, entry: string) { export function parseBuildDirectives(code: string): SourceDirectives { let out: SourceDirectives = emptyDirectives(); if (!code) return out; - let re = /^[ \t]*(?:\/\/|;)#(symbol|flag|tooldef)\b([^\n]*)/gmi; - let m; - while ((m = re.exec(code))) { + let re = /^[ \t]*(?:\/\/|;)#(symbol|flag|tooldef)\b([^\n]*)/i; + // per-line scan, not a global/multiline regex over the whole file -- see + // fixParamsWithDefines; the global matcher overflows the small worker stack + // ("too much recursion") on large source files + for (let line of code.split('\n')) { + let m = re.exec(line); + if (!m) continue; let kw = m[1].toLowerCase(); let raw = m[2].trim(); let parts = raw.split(/\s+/); @@ -743,10 +747,16 @@ export function fixParamsWithDefines(path: string, params) { } export function processEmbedDirective(code: string) { - let re3 = /^\s*#embed\s+"(.+?)"/gm; + if (!code.includes('#embed')) return code; + let re3 = /^\s*#embed\s+"(.+?)"/; // find #embed "filename.bin" and replace with C array data - return code.replace(re3, (m, m1) => { - let filename = m1; + // per-line match, not a global/multiline scan over the whole file -- see + // fixParamsWithDefines above; the global matcher overflows the small worker + // stack ("too much recursion") on large source files + return code.split('\n').map((line) => { + let m = re3.exec(line); + if (!m) return line; + let filename = m[1]; let filedata = store.getFileData(filename); let bytes = convertDataToUint8Array(filedata); if (!bytes) throw new Error('#embed: file not found: "' + filename + '"'); @@ -754,7 +764,7 @@ export function processEmbedDirective(code: string) { for (let i = 0; i < bytes.length; i++) { out += bytes[i].toString() + ','; } - return out.substring(0, out.length-1); - }); + return line.replace(re3, out.substring(0, out.length-1)); + }).join('\n'); } diff --git a/src/worker/tools/mcpp.ts b/src/worker/tools/mcpp.ts index 2aeffd53..15462688 100644 --- a/src/worker/tools/mcpp.ts +++ b/src/worker/tools/mcpp.ts @@ -56,7 +56,9 @@ export function preprocessMCPP(step: BuildStep, filesys: string) { if (errors.length) return { errors: errors }; var iout = FS.readFile("main.i", { encoding: 'utf8' }); - iout = iout.replace(/^#line /gm, '\n# '); + // per-line, not `replace(/^#line /gm, ...)` -- the multiline global matcher + // overflows the small worker stack ("too much recursion") on large output + iout = iout.split('\n').map((line) => line.startsWith('#line ') ? '\n# ' + line.substring(6) : line).join('\n'); try { var errout = FS.readFile("mcpp.err", { encoding: 'utf8' }); if (errout.length) {