diff --git a/src/bundler/options.zig b/src/bundler/options.zig index daea5ced59a3..6b32f1ff159e 100644 --- a/src/bundler/options.zig +++ b/src/bundler/options.zig @@ -1087,9 +1087,10 @@ pub const ESMConditions = struct { var require_condition_map = ConditionsMap.init(allocator); var style_condition_map = ConditionsMap.init(allocator); - try default_condition_amp.ensureTotalCapacity(defaults.len + 2 + if (allow_addons) 1 else 0 + conditions.len); - try import_condition_map.ensureTotalCapacity(defaults.len + 2 + if (allow_addons) 1 else 0 + conditions.len); - try require_condition_map.ensureTotalCapacity(defaults.len + 2 + if (allow_addons) 1 else 0 + conditions.len); + const addons_count: usize = if (allow_addons) 1 else 0; + try default_condition_amp.ensureTotalCapacity(defaults.len + 2 + addons_count + conditions.len); + try import_condition_map.ensureTotalCapacity(defaults.len + 2 + addons_count + conditions.len); + try require_condition_map.ensureTotalCapacity(defaults.len + 2 + addons_count + conditions.len); try style_condition_map.ensureTotalCapacity(defaults.len + 2 + conditions.len); import_condition_map.putAssumeCapacity("import", {}); diff --git a/test/bundler/bun-build-api.test.ts b/test/bundler/bun-build-api.test.ts index c1112743f02c..93ebf57d44ad 100644 --- a/test/bundler/bun-build-api.test.ts +++ b/test/bundler/bun-build-api.test.ts @@ -649,6 +649,36 @@ describe("Bun.build", () => { expect(await html?.text()).toContain(""); }, ); + + test("does not crash with many custom conditions", async () => { + // ESMConditions.init under-reserved capacity when allow_addons was true + // (the default) due to `if`-expression precedence, so passing several + // custom conditions overflowed putAssumeCapacity and crashed the bundler + // thread. Run in a subprocess since the crash aborts the whole process. + const dir = tempDirWithFiles("bun-build-api-conditions", { + "entry.ts": "export const x = 1;", + }); + await using proc = Bun.spawn({ + cmd: [ + bunExe(), + "-e", + ` + const result = await Bun.build({ + entrypoints: [${JSON.stringify(join(dir, "entry.ts"))}], + conditions: ["a", "b", "c", "d", "e", "f", "g", "h"], + }); + console.log("success:" + result.success); + `, + ], + env: bunEnv, + stdout: "pipe", + stderr: "pipe", + }); + const [stdout, stderr, exitCode] = await Promise.all([proc.stdout.text(), proc.stderr.text(), proc.exited]); + expect(stderr).toBe(""); + expect(stdout.trim()).toBe("success:true"); + expect(exitCode).toBe(0); + }); }); test.concurrent("macro with nested object", async () => {