From f2076e38b4f636bbd993dc391b2b09d4638e0c53 Mon Sep 17 00:00:00 2001 From: robobun <117481402+robobun@users.noreply.github.com> Date: Mon, 11 May 2026 04:45:13 +0000 Subject: [PATCH] bundler: fix ESMConditions capacity when user conditions are provided The expression `if (allow_addons) 1 else 0 + conditions.len` parses as `if (allow_addons) 1 else (0 + conditions.len)`, so when allow_addons is true the user-provided conditions were not counted towards the reserved capacity. With enough custom conditions this tripped the addOneAssumeCapacity assertion in debug builds and wrote past the allocation in release builds. --- src/bundler/options.zig | 7 ++++--- test/bundler/bun-build-api.test.ts | 18 ++++++++++++++++++ 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/src/bundler/options.zig b/src/bundler/options.zig index daea5ced59a3..19075362b889 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 extra: usize = if (allow_addons) 1 else 0; + try default_condition_amp.ensureTotalCapacity(defaults.len + 2 + extra + conditions.len); + try import_condition_map.ensureTotalCapacity(defaults.len + 2 + extra + conditions.len); + try require_condition_map.ensureTotalCapacity(defaults.len + 2 + extra + 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..af6526ad1382 100644 --- a/test/bundler/bun-build-api.test.ts +++ b/test/bundler/bun-build-api.test.ts @@ -811,6 +811,24 @@ identity(mod23); expect(text).toContain(" globalThis."); }); +test("many custom conditions does not crash", async () => { + const dir = tempDirWithFiles("bun-build-many-conditions", { + "entry.js": `console.log(1);`, + }); + + for (const target of ["bun", "browser", "node"] as const) { + for (const n of [1, 4, 6, 8, 12, 20]) { + const conditions = Array.from({ length: n }, (_, i) => `cond${i}`); + const build = await Bun.build({ + entrypoints: [join(dir, "entry.js")], + target, + conditions, + }); + expect(build.success).toBe(true); + } + } +}); + describe.concurrent("sourcemap boolean values", () => { test("sourcemap: true should work (boolean)", async () => { const dir = tempDirWithFiles("sourcemap-true-boolean", {