Fixes#23414
The code was asserting that all relative paths from .bin to package
binaries must start with "..\\" on Windows. This assumption breaks in
edge cases where the relative path has a different structure.
This commit:
- Replaces the assertion with a conditional check
- Handles both paths that start with "..\\" and those that don't
- Adds a regression test for issue #23414
The fix gracefully handles edge cases while maintaining the expected
behavior for the common case where binaries are in subdirectories
of node_modules.
Co-Authored-By: Claude <noreply@anthropic.com>
### What does this PR do?
When `process.nextTick` is overwritten, segv will be occured via
internal `processTick` call.
This patch fixes it.
### How did you verify your code works?
Tests.
---------
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
### What does this PR do?
Adds missing null checking for `Bun.CookieMap#delete`.
### How did you verify your code works?
Tests
---------
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
fixes: oven-sh/bun#23717
### What does this PR do?
- Align ProxyTunnel.onClose with
[HTTPClient.onClose](https://github.com/oven-sh/bun/blob/bun-v1.3.0/src/http.zig#L223-L241):
when a tunneled HTTPS response is in-progress and either
- parsing chunked trailers (trailer-line states), or
- transfer-encoding is identity with content_length == null while in
.body,
treat EOF as end-of-message and complete the request, rather than
ECONNRESET.
- Schedule proxy deref instead of deref inside callbacks to avoid
lifetime hazards.
### How did you verify your code works?
- `test/js/bun/http/proxy.test.ts`: raw TLS origin returns
close-delimited 200 OK; verified no ECONNRESET and body delivered.
- Test suite passes under bun bd test.
## Risk/compat
- Only affects CONNECT/TLS path. Direct HTTP/HTTPS unchanged. Behavior
mirrors existing
[HTTPClient.onClose](https://github.com/oven-sh/bun/blob/bun-v1.3.0/src/http.zig#L223-L241).
## Repro (minimal)
See issue; core condition is no Content-Length and no Transfer-Encoding
(close-delimited).
Co-authored-by: Ciro Spaciari <ciro.spaciari@gmail.com>
## Summary
Fixes `Buffer.isEncoding('')` to return `false` instead of `true`,
matching Node.js behavior.
## Description
Previously, `Buffer.isEncoding('')` incorrectly returned `true` in Bun,
while Node.js correctly returns `false`. This was caused by
`parseEnumerationFromView` in `JSBufferEncodingType.cpp` treating empty
strings (length 0) as valid utf8 encoding.
The fix modifies the switch statement to return `std::nullopt` for empty
strings, along with other invalid short strings.
## Changes
- Modified `src/bun.js/bindings/JSBufferEncodingType.cpp` to return
`std::nullopt` for empty strings
- Added regression test `test/regression/issue23966.test.ts`
## Test Plan
- [x] Test fails with `USE_SYSTEM_BUN=1 bun test
test/regression/issue23966.test.ts` (confirms bug exists)
- [x] Test passes with `bun bd test test/regression/issue23966.test.ts`
(confirms fix works)
- [x] Verified behavior matches Node.js v24.3.0
- [x] All test cases for valid/invalid encodings pass
Fixes#23966🤖 Generated with [Claude Code](https://claude.com/claude-code)
---------
Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude <noreply@anthropic.com>
### What does this PR do?
Adds missing exception check for ReadableStream.
### How did you verify your code works?
Tests
---------
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
## Summary
Fixes a bug where the `Bun.build()` API with `compile: true` did not
properly apply sourcemaps, even when `sourcemap: "inline"` was
specified. This resulted in error stack traces showing bundled virtual
paths (`/$bunfs/root/`) instead of actual source file names and line
numbers.
## Problem
The CLI `bun build --compile --sourcemap` worked correctly, but the
equivalent API call did not:
```javascript
// This did NOT work (before fix)
await Bun.build({
entrypoints: ['./app.js'],
compile: true,
sourcemap: "inline" // <-- Was ignored/broken
});
```
Error output showed bundled paths:
```
error: Error from helper module
at helperFunction (/$bunfs/root/app.js:4:9) // ❌ Wrong path
at main (/$bunfs/root/app.js:9:17) // ❌ Wrong line numbers
```
## Root Cause
The CLI explicitly overrides any sourcemap type to `.external` when
compile mode is enabled (in `/workspace/bun/src/cli/Arguments.zig`):
```zig
// when using --compile, only `external` works
if (ctx.bundler_options.compile) {
opts.source_map = .external;
}
```
The API implementation in `JSBundler.zig` was missing this override.
## Solution
Added the same sourcemap override logic to `JSBundler.zig` when compile
mode is enabled:
```zig
// When using --compile, only `external` sourcemaps work, as we do not
// look at the source map comment. Override any other sourcemap type.
if (this.source_map != .none) {
this.source_map = .external;
}
```
Now error output correctly shows source file names:
```
error: Error from helper module
at helperFunction (helper.js:2:9) // ✅ Correct file
at main (app.js:4:3) // ✅ Correct line numbers
```
## Tests
Added comprehensive test coverage in
`/workspace/bun/test/bundler/bun-build-compile-sourcemap.test.ts`:
- ✅ `sourcemap: "inline"` works
- ✅ `sourcemap: true` works
- ✅ `sourcemap: "external"` works
- ✅ Multiple source files show correct file names
- ✅ Without sourcemap, bundled paths are shown (expected behavior)
All tests:
- ✅ Fail with `USE_SYSTEM_BUN=1` (confirms bug exists)
- ✅ Pass with `bun bd test` (confirms fix works)
- ✅ Use `tempDir()` to avoid disk space issues
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
---------
Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude <noreply@anthropic.com>
### What does this PR do?
Adds support for `publicHoistPattern` in `bunfig.toml` and
`public-hoist-pattern` from `.npmrc`. This setting allows you to select
transitive packages to hoist to the root node_modules making them
available for all workspace packages.
```toml
[install]
# can be a string
publicHoistPattern = "@types*"
# or an array
publicHoistPattern = [ "@types*", "*eslint*" ]
```
`publicHoistPattern` only affects the isolated linker.
---
Adds `hoistPattern`. `hoistPattern` is the same as `publicHoistPattern`,
but applies to the `node_modules/.bun/node_modules` directory instead of
the root node_modules. Also the default value of `hoistPattern` is `*`
(everything is hoisted to `node_modules/.bun/node_modules` by default).
---
Fixes a determinism issue constructing the
`node_modules/.bun/node_modules` directory.
---
closes#23481closes#6160closes#23548
### How did you verify your code works?
Added tests for
- [x] only include patterns
- [x] only exclude patterns
- [x] mix of include and exclude
- [x] errors for unexpected expression types
- [x] excluding direct dependency (should still include)
- [x] match all with `*`
- [x] string and array expression types
---------
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
### What does this PR do?
`short` is signed in C++ by default and not unsigned. Switched to
`uint16_t` so it's unambiguous.
### How did you verify your code works?
There is a test
---------
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Fixes#19652
## Summary
Fixes a crash that occurred when using the `--production` flag with `bun
build`, particularly on Windows where assertions are enabled in release
builds.
## Root Cause
The crash occurred because an assertion for `jsx.development` was
running **before** `jsx.development` was properly configured. The
problematic sequence was:
1. Set `NODE_ENV=production` in env map
2. Call `configureDefines()` which reads `NODE_ENV` and calls
`setProduction(true)`, setting `jsx.development=false`
3. ❌ **Assert `jsx.development` is false** (assertion fired here, before
line 203 below)
4. Set `jsx.development = !production` on line 203 (too late)
## Changes
This PR reorders the code to move the assertion **after**
`jsx.development` is properly set:
1. Set both `BUN_ENV` and `NODE_ENV` to `"production"` in env map
2. Call `configureDefines()`
3. Set `jsx.development = !production` (now happens first)
4. ✅ **Assert `jsx.development` is false** (now runs after it's set)
Also adds `BUN_ENV=production` to match the behavior of setting
`NODE_ENV`.
## Test Plan
Added regression test in `test/regression/issue/19652.test.ts` that
verifies `bun build --production` doesn't crash.
The test:
- ✅ Passes on this branch
- ❌ Would fail on main (assertion failure)
🤖 Generated with [Claude Code](https://claude.com/claude-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: Jarred Sumner <jarred@jarredsumner.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
### What does this PR do?
Fixes a bug preventing workspace self dependencies from getting
symlinked to the workspace node_modules
Fixes#23605
### How did you verify your code works?
Added a test for normal `"workspace:*"` deps, and `"workspace:."` under
a different name.
---------
Co-authored-by: Jarred Sumner <jarred@jarredsumner.com>
## Summary
Fixed an off-by-one error in buffer allocation for several path module
functions when handling paths longer than `PATH_SIZE` (typically 4096
bytes on most platforms).
## Changes
- `normalizeJS_T`: Added +1 to buffer allocation for null terminator
- `relativeJS_T`: Added +1 to buffer allocation for null terminator
- `toNamespacedPathJS_T`: Added +9 bytes (8 for possible UNC prefix + 1
for null terminator)
## Test plan
- Added tests for `path.normalize()` with paths up to 100,000 characters
- Added tests for `path.relative()` with very long paths
- All existing path tests continue to pass
The issue occurred because when a path is exactly equal to or longer
than `PATH_SIZE`, the buffer was allocated with size equal to the path
length, but then a null terminator was written at `buf[bufSize]`, which
was out of bounds.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
---------
Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Jarred Sumner <jarred@jarredsumner.com>
## Summary
Fixes a panic that occurred when a WebSocket close frame's payload was
split across multiple TCP packets.
## The Bug
The panic occurred at `websocket_client.zig:681`:
```
panic: index out of bounds: index 24, len 14
```
This happened when:
- A close frame had a payload of 24 bytes (2 byte code + 22 byte reason)
- The first TCP packet contained 14 bytes (header + partial payload)
- The code tried to access `data[2..24]` causing the panic
## Root Causes
1. **Bounds checking issue**: The code assumed all close frame data
would arrive in one packet and tried to `@memcpy` without verifying
sufficient data was available.
2. **Premature flag setting**: `close_received = true` was set
immediately upon entering the close state. This prevented `handleData`
from being called again when the remaining bytes arrived (early return
at line 354).
## The Fix
Implemented proper fragmentation handling for close frames, following
the same pattern used for ping frames:
- Added `close_frame_buffering` flag to track buffering state
- Buffer incoming data incrementally using the existing
`ping_frame_bytes` buffer
- Track total expected length and bytes received so far
- Only set `close_received = true` after all bytes are received
- Wait for more data if the frame is incomplete
## Testing
- Created two regression tests that fragment close frames across
multiple packets
- All existing WebSocket tests pass (`test/js/web/websocket/`)
- Verified the original panic no longer occurs
## Related
This appears to be the root cause of crashes reported on Windows when
WebSocket connections close, particularly when close frames have reasons
that get fragmented by the network stack.
---
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
---------
Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Jarred Sumner <jarred@jarredsumner.com>
### What does this PR do?
Let MySQL unref when idle and make sure that is behaving like this.
Only set up the timers after all status changes are complete since the
timers rely on the status to determine timeouts, this was causing the
CPU usage spike to 100% (thats why only happened in TLS)
CPU usage it self will be improved in
https://github.com/oven-sh/bun/pull/23700 not in this PR
Fixes: https://github.com/oven-sh/bun/issues/23273
Fixes: https://github.com/oven-sh/bun/issues/23256
### How did you verify your code works?
Test
---------
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
### What does this PR do?
This PR implements support for the `email` field in `.npmrc` files for
registry scope authentication. Some private registries (particularly
Nexus) require the email field to be specified in the registry
configuration alongside username/password or token authentication.
The email field can now be specified in `.npmrc` files like:
```ini
//registry.example.com/:email=user@example.com
//registry.example.com/:username=myuser
//registry.example.com/:_password=base64encodedpassword
```
### How did you verify your code works?
1. **Built Bun successfully** - Confirmed the code compiles without
errors using `bun bd --debug`
2. **Wrote comprehensive unit tests** - Added two test cases to
`test/cli/install/npmrc.test.ts`:
- Test for standalone email field parsing
- Test for email combined with username/password authentication
3. **Verified tests pass** - Ran `bun bd test
test/cli/install/npmrc.test.ts -t "email"` and confirmed both tests
pass:
```
✓ 2 pass
✓ 0 fail
✓ 6 expect() calls
```
4. **Code changes include**:
- Added `email` field to `NpmRegistry` struct in `src/api/schema.zig`
- Updated `encode()` and `decode()` methods to handle the email field
- Modified `ini.zig` to parse and store the email field from `.npmrc`
- Removed email from the unsupported options warning (certfile and
keyfile remain unsupported)
- Updated all `NpmRegistry` struct initializations to include the email
field
- Updated `loadNpmrcFromJS` test API to return the email field
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude <noreply@anthropic.com>
### What does this PR do?
Fixes#23489
The YAML parser was incorrectly treating `...` inside double-quoted
strings as document end markers, causing parse errors for strings
containing ellipsis, particularly affecting internationalized text.
### Example of the bug:
```yaml
balance: "👛 لا تمتلك محفظة... !"
```
This would fail with: `error: Unexpected document end`
### Root cause:
The bug was introduced in commit fcbd57ac48 which attempted to optimize
document marker detection by using `self.line_indent == .none` instead
of tracking newlines with a local flag. However, this check was
incomplete - it didn't track whether we had just processed a newline
character.
### The fix:
Restored the `nl` (newline) flag pattern from the single-quoted scanner
and combined it with the `line_indent` check. Document markers `...` and
`---` are now only recognized when **all** of these conditions are met:
1. We're after a newline (`nl == true`)
2. We're at column 0 (`self.line_indent == .none`)
3. Followed by whitespace or EOF
This allows `...` to appear freely in double-quoted strings while still
correctly recognizing actual document end markers at the start of lines.
### How did you verify your code works?
1. Reproduced the original issue from #23489
2. Applied the fix and verified all test cases pass:
- Original Arabic text with emoji: `"👛 لا تمتلك محفظة... !"`
- Various `...` positions: start, middle, end
- Both single and double quotes
- Multiline strings with indented `...` (issue #22392)
3. Created regression test in `test/regression/issue/23489.test.ts`
4. Verified existing YAML tests still pass (514 pass, up from 513)
cc @dylan-conway for review
---------
Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Jarred Sumner <jarred@jarredsumner.com>
Co-authored-by: Dylan Conway <dylan.conway567@gmail.com>
## Summary
Fixes a panic that occurred when passing `NumberObject` or
`BooleanObject` as MySQL query parameters.
**Panic message:** `A JavaScript exception was thrown, but it was
cleared before it could be read.`
## Root Cause
The `FieldType.fromJS` function in `src/sql/mysql/MySQLTypes.zig` was
returning `error.JSError` without throwing a JavaScript exception first
for:
- `NumberObject` (created via `new Number(42)`)
- `BooleanObject` (created via `new Boolean(true)`)
- Non-indexable types
This violated the contract that `error.JSError` means "an exception has
already been thrown and is ready to be taken."
## Call Chain
1. User executes `await sql\`SELECT ${new Number(42)} as value\``
2. `FieldType.fromJS()` detects `.NumberObject` and returns
`error.JSError` without throwing
3. Error propagates to `MySQLQuery.runPreparedQuery()`
4. Code checks `hasException()` → returns false (no exception exists!)
5. Calls `mysqlErrorToJS(globalObject, "...", error.JSError)`
6. `mysqlErrorToJS` tries to `takeException(error.JSError)` but there's
no exception
7. **PANIC**
## Fix
The fix throws a proper exception with a helpful message before
returning `error.JSError`:
- `"Cannot bind NumberObject to query parameter. Use a primitive number
instead."`
- `"Cannot bind BooleanObject to query parameter. Use a primitive
boolean instead."`
- `"Cannot bind this type to query parameter"`
## Test Plan
Added regression tests in `test/js/sql/sql-mysql.test.ts`:
- Test passing `NumberObject` as parameter
- Test passing `BooleanObject` as parameter
Both tests verify that a proper error is thrown instead of crashing.
Verified manually with local MySQL server that:
- ✅ NumberObject now throws proper error (was crashing)
- ✅ BooleanObject now throws proper error (was crashing)
- ✅ Primitive numbers still work correctly
🤖 Generated with [Claude Code](https://claude.com/claude-code)
---------
Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude <noreply@anthropic.com>
## Summary
Adds a new `--only-failures` flag to `bun test` that only displays test
failures, similar to `--dots` but without printing dots for each test.
## Motivation
When running large test suites or in CI environments, users often only
care about test failures. The existing `--dots` reporter reduces
verbosity by showing dots, but still requires visual scanning to find
failures. The `--only-failures` flag provides a cleaner output by
completely suppressing passing tests.
## Changes
- Added `--only-failures` CLI flag in `Arguments.zig`
- Added `only_failures` boolean to the test reporters struct in
`cli.zig`
- Updated test output logic in `test_command.zig` to skip non-failures
when flag is set
- Updated `jest.zig` and `bun_test.zig` to handle the new flag
- Added comprehensive tests in `only-failures.test.ts`
## Usage
```bash
bun test --only-failures
```
Example output (only shows failures):
```
test/example.test.ts:
(fail) failing test
error: expect(received).toBe(expected)
Expected: 3
Received: 2
5 pass
1 skip
2 fail
Ran 8 tests across 1 file.
```
## Test Plan
- Verified `--only-failures` flag only shows failing tests
- Verified normal test output still works without the flag
- Verified `--dots` reporter still works correctly
- Added regression tests with snapshot comparisons
🤖 Generated with [Claude Code](https://claude.com/claude-code)
---------
Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: pfg <pfg@pfg.pw>
Fixes#23569
## Summary
HTML imports require bundling to work correctly, as they need to process
and transform linked assets (JS/CSS). When `--no-bundle` is used, no
bundling or transformation happens, which causes a crash.
This change adds validation to detect HTML entrypoints when
`--no-bundle` is used and provides a clear error message explaining that
"HTML imports are only supported when bundling".
## Changes
- Added validation in `src/cli/build_command.zig` to check for HTML
entrypoints when `--no-bundle` flag is used
- Shows clear error message: "HTML imports are only supported when
bundling"
- Added regression tests in `test/regression/issue/23569.test.ts`
## Test Plan
### Before
```bash
$ bun build ./index.html --no-bundle
# Crashes without helpful error
```
### After
```bash
$ bun build ./index.html --no-bundle
error: HTML imports are only supported when bundling
```
### Tests
- ✅ Test with `--no-bundle` flag errors correctly
- ✅ Test with `--no-bundle --outdir` errors correctly
- ✅ Test without `--no-bundle` works normally
- ✅ All 3 regression tests pass
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
---------
Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude <noreply@anthropic.com>
### What does this PR do?
Fixes#23521
### How did you verify your code works?
Added 3 previously failing tests for `"bin"`, `"directories.bin"`, and
deduplicating entry in both `"bin.directories"` and `"files"`
---------
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
## Summary
Fixes two critical bugs in Bun Shell:
1. **Memory leaks & incorrect GC reporting**: Shell objects weren't
reporting their memory usage to JavaScriptCore's garbage collector,
causing memory to accumulate unchecked. Also fixes a leak where
`ShellArgs` wasn't being freed in `Interpreter.finalize()`.
2. **Blocking I/O on macOS**: Fixes a bug where writing large amounts of
data (>1MB) to pipes would block the main thread on macOS. The issue:
`sendto()` with `MSG_NOWAIT` flag blocks on macOS despite the flag, so
we now avoid the socket fast path unless the socket is already
non-blocking.
## Changes
- Adds `memoryCost()` and `estimatedSize()` implementations across shell
AST nodes, interpreter, and I/O structures
- Reports estimated memory size to JavaScriptCore GC via
`vm.heap.reportExtraMemoryAllocated()`
- Fixes missing `this.args.deinit()` call in interpreter finalization
- Fixes `BabyList.memoryCost()` to return bytes, not element count
- Conditionally uses socket fast path in IOWriter based on platform and
socket state
## Test plan
- [x] New test: `shell-leak-args.test.ts` - validates memory doesn't
leak during parsing/execution
- [x] New test: `shell-blocking-pipe.test.ts` - validates large pipe
writes don't block the main thread
- [x] Existing shell tests pass
🤖 Generated with [Claude Code](https://claude.com/claude-code)
---------
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Claude Bot <claude-bot@bun.sh>
## Summary
Fixes a panic that occurred when formatting deeply nested objects with
many properties in test output.
## Problem
The `writeIndent()` function in `pretty_format.zig:648` performed
`written * 2` which triggered integer overflow checking in debug builds
when formatting complex nested structures.
**Original crash:**
```
panic: integer overflow
writeIndent at bun.js/test/pretty_format.zig:648
```
**Platform:** Windows x86_64_baseline, Bun v1.3.0
## Solution
Changed from:
```zig
try writer.writeAll(buf[0 .. written * 2]);
```
To:
```zig
const byte_count = @min(buf.len, written *% 2);
try writer.writeAll(buf[0..byte_count]);
```
- Used wrapping multiplication (`*%`) to prevent overflow panic
- Added bounds checking with `@min(buf.len, ...)` for safety
- Maintains correct behavior while preventing crashes
## Test
Added regression test at
`test/js/bun/test/pretty-format-overflow.test.ts` that:
- Creates deeply nested objects (500 levels with 50 properties each)
- Verifies no panic/overflow/crash occurs when formatting
- Uses exact configuration that triggered the original crash
## Verification
- ✅ Test passes with the fix
- ✅ Test would crash without the fix (in debug builds)
- ✅ No changes to behavior, only safety improvement
Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Jarred Sumner <jarred@jarredsumner.com>
### What does this PR do?
Fixes printing `import.meta.url` and others with `--bytecode`. Fixes
#14954.
Fixes printing `__toESM` when output module format is CJS and input
module format is ESM.
The key change is that `__toESM`'s `isNodeMode` parameter now depends on
the **input module type** (whether the importing file uses ESM syntax
like `import`/`export`) rather than the output format. This matches
Node.js ESM behavior where importing CommonJS from `.mjs` files always
wraps the entire `module.exports` object as the default export, ignoring
`__esModule` markers.
### How did you verify your code works?
Added comprehensive test suite in `test/bundler/bundler_cjs.test.ts`
with **23 tests** covering:
#### Core Behaviors:
- ✅ Files using `import` syntax always get `isNodeMode=1`, which
**ignores `__esModule`** markers and wraps the entire CJS module as
default
- ✅ This matches Node.js ESM semantics for importing CJS from `.mjs`
files
- ✅ Different CJS export patterns (`exports.x`, `module.exports = ...`,
functions, primitives)
- ✅ Named, default, and namespace (`import *`) imports
- ✅ Different targets (node, browser, bun) - all behave the same
- ✅ Different output formats (esm, cjs) - format doesn't affect the
behavior
- ✅ `.mjs` files re-exporting from `.cjs`
- ✅ Deep re-export chains
- ✅ Edge cases (non-boolean `__esModule`, `__esModule=false`, etc.)
#### Test Results:
- **With this PR's changes**: All 23 tests pass ✅
- **Without this PR (system bun)**: 22 pass, 1 fails (the one testing
that `__esModule` is ignored with import syntax + CJS format)
The failing test with system bun demonstrates the bug being fixed:
currently, format=cjs with import syntax still respects `__esModule`,
but it should ignore it (matching Node.js behavior).
---------
Co-authored-by: Jarred Sumner <jarred@jarredsumner.com>
Co-authored-by: Claude Bot <claude-bot@bun.sh>
### 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>
Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude <noreply@anthropic.com>
## Summary
Fixed an unsigned integer underflow in the bounds check for
`writeBigInt64LE`, `writeBigInt64BE`, `writeBigUInt64LE`, and
`writeBigUInt64BE` methods.
## Problem
When `byteLength < 8`, the bounds check `offset > byteLength - 8` would
cause unsigned integer underflow (since both are `size_t`), resulting in
a large positive number that would pass the check. This allowed
out-of-bounds writes and caused ASAN use-after-poison errors.
**Reproduction:**
```js
const buf = Buffer.from("Hello World");
const slice = buf.slice(0, 5);
slice.writeBigUInt64BE(4096n, 10000); // ASAN error!
```
## Solution
Added an explicit `byteLength < 8` check before the subtraction to
prevent the underflow. The fix is applied to all four functions:
- `writeBigInt64LE` (src/bun.js/bindings/JSBuffer.cpp:2464)
- `writeBigInt64BE` (src/bun.js/bindings/JSBuffer.cpp:2504)
- `writeBigUInt64LE` (src/bun.js/bindings/JSBuffer.cpp:2543)
- `writeBigUInt64BE` (src/bun.js/bindings/JSBuffer.cpp:2582)
## Test plan
- Added comprehensive regression tests covering all edge cases
- Verified the original reproduction case now throws a proper RangeError
instead of crashing
- All tests pass
🤖 Generated with [Claude Code](https://claude.com/claude-code)
---------
Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Jarred Sumner <jarred@jarredsumner.com>
## Summary
Fixes an assertion failure that occurred when `URLSearchParams.toJSON()`
was called with numeric string keys.
## The Problem
When using numeric string keys (e.g., `"39208"`, `"0"`, `"100"`),
calling `toJSON()` would trigger:
```
ASSERTION FAILED: !parseIndex(propertyName)
cache/webkit-6d0f3aac0b817cc0/include/JavaScriptCore/JSObjectInlines.h:444
```
Reproduction:
```javascript
const params = new URLSearchParams();
params.set("39208", "updated");
params.toJSON(); // crashes
```
## Root Cause
The `getInternalProperties` function in `JSURLSearchParams.cpp` was
using `putDirect()` to add properties to the result object. However,
`putDirect()` cannot be used with property names that can be parsed as
array indices - JSC expects such properties to use indexed storage
instead.
## The Fix
- Replace `putDirect()` with `putDirectMayBeIndex()`, which
automatically handles both regular properties and numeric indices
- Replace `getDirect()` with `get()` to properly retrieve values for
both types of properties
## Test Plan
Added comprehensive tests to `test/js/web/html/URLSearchParams.test.ts`:
- ✅ Single numeric string keys
- ✅ Multiple numeric keys
- ✅ Mixed numeric and non-numeric keys
- ✅ Duplicate numeric keys
- ✅ Extra arguments (original crash case)
All tests pass, and the original crash no longer occurs.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
---------
Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Jarred Sumner <jarred@jarredsumner.com>
### What does this PR do?
Fixes#23621.
Note that the quality of this code is quite low, but since Redis is
getting a rewrite, this is a stop-gap. The tests are what really matters
here.
This whole PR is claude.
### How did you verify your code works?
CI.
---------
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
## Summary
Fixes a panic that occurred when `console.log()` tried to format a Set
or Map instance with a non-numeric `size` property.
## Issue
When a Set or Map subclass overrides the `size` property with a
non-numeric value (like a constructor function, string, or other
object), calling `console.log()` on the instance would trigger a panic:
```javascript
class C1 extends Set {
constructor() {
super();
Object.defineProperty(this, "size", {
writable: true,
enumerable: true,
value: Set
});
console.log(this); // panic!
}
}
new C1();
```
## Root Cause
In `src/bun.js/ConsoleObject.zig`, the Map and Set formatting code
called `toInt32()` directly on the `size` property value. This function
asserts that the value is not a Cell (objects/functions), causing a
panic when `size` was overridden with non-numeric values.
## Solution
Changed both Map and Set formatting to use `coerce(i32, globalThis)`
instead of `toInt32()`. This properly handles non-numeric values using
JavaScript's standard type coercion rules and propagates any coercion
errors appropriately.
## Test Plan
Added regression tests to `test/js/bun/util/inspect.test.js` that verify
Set and Map instances with overridden non-numeric `size` properties can
be inspected without panicking.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude <noreply@anthropic.com>
## Summary
This PR adds support for the `--pass-with-no-tests` CLI flag to the test
runner, addressing issue #20814.
With the latest v1.2.8 release, the test runner now fails when no tests
match a filter. While this is useful for agentic coding workflows, there
are legitimate cases where the previous behavior is preferred, such as
in monorepos where a standard test file pattern is used as a filter but
not all packages contain tests.
This flag makes the test runner behave like Jest and Vitest, exiting
with code 0 when no tests are found.
## Changes
- Added `--pass-with-no-tests` flag to CLI arguments in
`src/cli/Arguments.zig`
- Added `pass_with_no_tests` field to `TestOptions` struct in
`src/cli.zig`
- Updated test runner logic in `src/cli/test_command.zig` to respect the
flag
- Added comprehensive tests in
`test/cli/test/pass-with-no-tests.test.ts`
## Test Plan
All new tests pass:
- ✅ `--pass-with-no-tests` exits with 0 when no test files found
- ✅ `--pass-with-no-tests` exits with 0 when filters match no tests
- ✅ Without flag, still exits with 1 when no tests found (preserves
existing behavior)
- ✅ `--pass-with-no-tests` still fails when actual tests fail
Closes#20814🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: pfg <pfg@pfg.pw>