Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion src/semver/SemverQuery.rs
Original file line number Diff line number Diff line change
Expand Up @@ -722,7 +722,11 @@ pub fn parse(input: &[u8], sliced: SlicedString) -> Result<Group, AllocError> {
let mut token = Token::default();
let mut prev_token = Token::default();

let mut count: u8 = 0;
// u32, not u8: a range with >=256 `||`/whitespace comparators overflows a
// u8 on the 256th increment. Zig's ReleaseFast wrapped (256 -> 0) silently;
// Rust's debug profile has overflow-checks and would panic+abort. `count`
// is only ever compared `== 0`, so the wider type is strictly more correct.
let mut count: u32 = 0;
Comment thread
robobun marked this conversation as resolved.
let mut skip_round;
let mut is_or = false;

Expand Down
16 changes: 16 additions & 0 deletions test/cli/install/semver.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
// IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

import { bunEnv, bunExe } from "harness";
import { unsortedPrereleases } from "./semver-fixture.js";
const { satisfies, order } = Bun.semver;

Expand Down Expand Up @@ -738,3 +739,18 @@
expect(unsortedPrereleases.sort(Bun.semver.order)).toMatchSnapshot();
});
});

test("a version range with >=256 || comparators does not abort", async () => {
const range = Array(300).fill("1.0.0").join(" || ");
await using proc = Bun.spawn({
cmd: [bunExe(), "-e", `process.stdout.write(String(Bun.semver.satisfies("1.0.0", ${JSON.stringify(range)})))`],
env: bunEnv,
stdout: "pipe",
stderr: "pipe",
});
const [stdout, exitCode] = await Promise.all([proc.stdout.text(), proc.exited]);

Check warning on line 751 in test/cli/install/semver.test.ts

View check run for this annotation

Claude / Claude Code Review

Test pipes stderr but never reads it

nit: `stderr: "pipe"` is set but `proc.stderr` is never read, so if this regression ever recurs the Rust panic message gets silently discarded and CI will only show `stdout=""` / `exitCode=133` with no diagnostic. Consider adding `proc.stderr.text()` to the `Promise.all` and asserting `expect(stderr).toBe("")` (per the spawn-test pattern in test/CLAUDE.md), or just drop `stderr: "pipe"` so failures inherit to the runner output.
Comment thread
robobun marked this conversation as resolved.
Outdated
// The 256th comparator overflowed a u8 counter -> panic+abort (exit 133) in
// debug builds. Fixed: a wider counter parses it fine, like released Bun.
expect(stdout).toBe("true");
expect(exitCode).toBe(0);
});
Loading