## What does this PR do?
Fixes https://github.com/oven-sh/bun/issues/22650
Fixes https://github.com/oven-sh/bun/issues/22615
Fixes https://github.com/oven-sh/bun/issues/22603
Fixes https://github.com/oven-sh/bun/issues/22602
Fixes a crash that occurred when running shell commands through `bun
run` (package.json scripts) on Windows that use the `&&` operator
followed by an external command.
### The Problem
The minimal reproduction was:
```bash
bun exec 'echo && node --version'
```
This would crash with: `panic(main thread): attempt to use null value`
### Root Causes
Two issues were causing the crash:
1. **Missing top_level_dir**: When `runPackageScriptForeground` creates
a MiniEventLoop for running package scripts, it wasn't setting the
`top_level_dir` field. This caused a null pointer dereference when the
shell tried to access it.
2. **MovableIfWindowsFd handling**: After PR #21800 introduced
`MovableIfWindowsFd` to handle file descriptor ownership on Windows, the
`IOWriter.fd` could be moved to libuv, leaving it null. When the shell
tried to spawn an external command after a `&&` operator, it would crash
trying to access this null fd.
### The Fix
1. Set `mini.top_level_dir = cwd` after initializing the MiniEventLoop
in `run_command.zig`
2. In `IO.zig`, when the fd has been moved to libuv (is null), use
`.inherit` for stdio instead of trying to pass the null fd
### How did you verify your code works?
- Added a regression test that reproduces the issue
- Verified the test fails without the fix and passes with it
- Tested the minimal reproduction command directly
- The fix correctly allows both commands in the `&&` chain to execute
```bash
# Before fix: crashes
> bun exec 'echo test && node --version'
panic(main thread): attempt to use null value
# After fix: works correctly
> bun exec 'echo test && node --version'
test
v22.4.1
```
<sub>
also probably fixes#22615 and fixes#22603 and fixes#22602
</sub>
---------
Co-authored-by: Zack Radisic <zack@theradisic.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
* Define a generic allocator interface to enable static polymorphism for
allocators (see `GenericAllocator` in `src/allocators.zig`). Note that
`std.mem.Allocator` itself is considered a generic allocator.
* Add utilities to `bun.allocators` for working with generic allocators.
* Add a new namespace, `bun.memory`, with basic utilities for working
with memory and objects (`create`, `destroy`, `initDefault`, `deinit`).
* Add `bun.DefaultAllocator`, a zero-sized generic allocator type whose
`allocator` method simply returns `bun.default_allocator`.
* Implement the generic allocator interface in `AllocationScope` and
`MimallocArena`.
* Improve `bun.threading.GuardedValue` (now `bun.threading.Guarded`).
* Improve `bun.safety.AllocPtr` (now `bun.safety.CheckedAllocator`).
(For internal tracking: fixes STAB-1085, STAB-1086, STAB-1087,
STAB-1088, STAB-1089, STAB-1090, STAB-1091)
## Summary
- Fixes crash when running shell commands with variable assignments
piped to other commands
- Resolves#15714
## Problem
The shell was crashing with "Invalid tag" error when running commands
like:
```bash
bun exec "FOO=bar BAR=baz | echo hi"
```
## Root Cause
In `Pipeline.zig`, the `cmds` array was allocated with the wrong size:
- It used `node.items.len` (which includes assignments)
- But only filled entries for actual commands (assignments are skipped
in pipelines)
- This left uninitialized memory that caused crashes when accessed
## Solution
Changed the allocation to use the correct `cmd_count` instead of
`node.items.len`:
```zig
// Before
this.cmds = if (cmd_count >= 1) bun.handleOom(this.base.allocator().alloc(CmdOrResult, this.node.items.len)) else null;
// After
this.cmds = if (cmd_count >= 1) bun.handleOom(this.base.allocator().alloc(CmdOrResult, cmd_count)) else null;
```
## Test plan
✅ Added comprehensive regression test in
`test/regression/issue/15714.test.ts` that:
- Tests the exact case from the issue
- Tests multiple assignments
- Tests single assignment
- Tests assignments in middle of pipeline
- Verified test fails on main branch (exit code 133 = SIGTRAP)
- Verified test passes with fix
🤖 Generated with [Claude Code](https://claude.ai/code)
---------
Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Zack Radisic <56137411+zackradisic@users.noreply.github.com>
Replace `catch bun.outOfMemory()`, which can accidentally catch
non-OOM-related errors, with either `bun.handleOom` or a manual `catch
|err| switch (err)`.
(For internal tracking: fixes STAB-1070)
---------
Co-authored-by: Dylan Conway <dylan.conway567@gmail.com>
### What does this PR do?
### How did you verify your code works?
---------
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
### What does this PR do?
- Fixes `$.braces(...)` not working properly on non-ascii inputs
- Switches braces code to use `SmallList` to support more deeply nested
brace expansion
---------
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
### What does this PR do?
Fixes a crash related to pipelines
---------
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Jarred Sumner <jarred@jarredsumner.com>
## Summary
- Fixed shell lexer to properly store error messages using TextRange
instead of direct string slices
- This prevents potential use-after-free issues when error messages are
accessed after the lexer's string pool might have been reallocated
- Added test coverage for shell syntax error reporting
## Changes
- Changed `LexError.msg` from `[]const u8` to `Token.TextRange` to store
indices into the string pool
- Added `TextRange.slice()` helper method for converting ranges back to
string slices
- Updated error message concatenation logic to use the new range-based
approach
- Added test to verify syntax errors are reported correctly
## Test plan
- [x] Added test case for invalid shell syntax error reporting
- [x] Existing shell tests continue to pass
- [x] Manual testing of various shell syntax errors
closes BAPI-2232
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-authored-by: Claude <noreply@anthropic.com>
Ensure we aren't using multiple allocators with the same list by storing
a pointer to the allocator in debug mode only.
This check is stricter than the bare minimum necessary to prevent
illegal behavior, so CI may reveal certain uses that fail the checks but
don't cause IB. Most of these cases should probably be updated to comply
with the new requirements—we want these types' invariants to be clear.
(For internal tracking: fixes ENG-14987)
### What does this PR do?
Lets us write and run unit tests directly in Zig.
Running Zig unit tests in CI is blocked by https://github.com/ziglang/zig/issues/23281. We can un-comment relevant code once this is fixed.
#### Workflow
> I'll finish writing this up later, but some initial points are below.
> Tl;Dr: `bun build:test`
Test binaries can be made for any kind of build. They are called `<bun>-test` and live next to their corresponding `bun` bin. For example, debug tests compile to `build/debug/bun-debug-test`.
Test binaries re-use most cmake/zig build steps from normal bun binaries, so building one after a normal bun build is pretty fast.
### How did you verify your code works?
I tested that my tests run tests.