mirror of
https://github.com/oven-sh/bun
synced 2026-02-13 04:18:58 +00:00
fix: correct off-by-one bounds checks in bundler and package installer (#25582)
## Summary
- Fix two off-by-one bounds check errors that used `>` instead of `>=`
- Both bugs could cause undefined behavior (array out-of-bounds access)
when an index equals the array length
## The Bugs
### 1. `src/install/postinstall_optimizer.zig:62`
```zig
// Before (buggy):
if (resolution > metas.len) continue;
const meta: *const Meta = &metas[resolution]; // Out-of-bounds when resolution == metas.len
// After (fixed):
if (resolution >= metas.len) continue;
```
### 2. `src/bundler/linker_context/doStep5.zig:10`
```zig
// Before (buggy):
if (id > c.graph.meta.len) return;
const resolved_exports = &c.graph.meta.items(.resolved_exports)[id]; // Out-of-bounds when id == c.graph.meta.len
// After (fixed):
if (id >= c.graph.meta.len) return;
```
## Why These Are Bugs
Valid array indices are `0` to `len - 1`. When `index == len`:
- `index > len` evaluates to `false` → check passes
- `array[index]` accesses `array[len]` → out-of-bounds / undefined
behavior
## Codebase Patterns
The rest of the codebase correctly uses `>=` for these checks:
- `lockfile.zig:484`: `if (old_resolution >= old.packages.len)
continue;`
- `lockfile.zig:522`: `if (old_resolution >= old.packages.len)
continue;`
- `LinkerContext.zig:389`: `if (source_index >= import_records_list.len)
continue;`
- `LinkerContext.zig:1667`: `if (source_index >= c.graph.ast.len) {`
## Test plan
- [x] Verified fix aligns with existing codebase patterns
- [ ] CI passes
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -7,7 +7,7 @@ pub fn doStep5(c: *LinkerContext, source_index_: Index, _: usize) void {
|
||||
defer trace.end();
|
||||
|
||||
const id = source_index;
|
||||
if (id > c.graph.meta.len) return;
|
||||
if (id >= c.graph.meta.len) return;
|
||||
|
||||
const worker: *ThreadPool.Worker = ThreadPool.Worker.get(@fieldParentPtr("linker", c));
|
||||
defer worker.unget();
|
||||
|
||||
@@ -59,7 +59,7 @@ pub const PostinstallOptimizer = enum {
|
||||
// Loop through the list of optional dependencies with platform-specific constraints
|
||||
// Find a matching target-specific dependency.
|
||||
for (resolutions) |resolution| {
|
||||
if (resolution > metas.len) continue;
|
||||
if (resolution >= metas.len) continue;
|
||||
const meta: *const Meta = &metas[resolution];
|
||||
if (meta.arch == .all or meta.os == .all) continue;
|
||||
if (meta.arch.isMatch(target_cpu) and meta.os.isMatch(target_os)) {
|
||||
|
||||
Reference in New Issue
Block a user