Commit Graph

4289 Commits

Author SHA1 Message Date
Claude Bot
d43b3e3119 Normalize ucs2/utf16le encoding aliases
Addresses CodeRabbit review feedback:

**Issue**: ucs2 and utf16le were not being treated as equivalent aliases,
causing transcode("utf16le", "ucs2") to fail with "Unsupported encoding
combination" error.

**Fix**:
- Normalize ucs2 to utf16le before processing
- This ensures the same-encoding fast path works for both aliases
- All switch cases now treat them identically
- Removed ucs2 from supported encoding checks (redundant after normalization)

**Tests Added**:
- utf16le → ucs2 transcoding
- ucs2 → utf16le transcoding
- ucs2 → utf8 transcoding

All tests pass (22 custom + Node.js compatibility).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-31 01:32:51 +00:00
Claude Bot
6d592d633b Fix ASCII 7-bit limit and add ASCII↔Latin1 transcoding
Addresses CodeRabbit review feedback:

1. **Enforce 7-bit ASCII limit (0x00-0x7F)**
   - UTF-8 → ASCII now clamps to 0x7F instead of 0xFF
   - UTF-16 → ASCII now clamps to 0x7F instead of 0xFF
   - Characters above 0x7F are replaced with '?'

2. **Implement ASCII ↔ Latin1 transcoding**
   - Added ASCII → Latin1 (simple copy, all ASCII is valid Latin1)
   - Added Latin1 → ASCII (clamp bytes > 0x7F to '?')
   - Fixes regression where these conversions would throw

3. **Add comprehensive tests**
   - Test ASCII to Latin1 conversion
   - Test Latin1 to ASCII with high byte replacement
   - Test 7-bit ASCII enforcement from UTF-8
   - Test Latin1 character preservation

All tests pass (19 custom + Node.js compatibility).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-31 01:18:19 +00:00
Claude Bot
d16bbd80d3 Fix error handling and enable Node.js transcode tests
- Use Bun::ERR::INVALID_ARG_TYPE for better error messages
- Add exception check for empty buffer creation
- Enable hasIntl in common/index.js for Bun compatibility
- Update test-icu-transcode.js to handle Bun's error message format

All Node.js transcode tests now pass.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-31 01:01:25 +00:00
Claude Bot
cd786fd0ba Implement transcode function for node:buffer
This commit adds support for the transcode function in node:buffer,
which converts Buffer contents between different character encodings.

Implementation:
- Added transcodeBuffer helper function in JSBuffer.cpp that performs
  encoding conversions using simdutf
- Supports utf8, utf16le/ucs2, latin1, and ascii encodings
- Invalid characters are replaced with '?' when transcoding to ASCII/Latin1
- Uses SIMDUTF for fast encoding conversions

Added comprehensive test suite covering:
- UTF-8 to ASCII/Latin1 with replacement chars
- UTF-8 to/from UTF-16LE
- Latin1 to/from UTF-8 and UTF-16LE
- Empty buffers and same-encoding passthrough
- Error handling for invalid inputs

Fixes #24235

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-31 00:54:19 +00:00
robobun
4f1b90ad1d Fix EventEmitter crash in removeAllListeners with removeListener meta-listener (#24148)
## Summary

Fixes #24147

- Fixed EventEmitter crash when `removeAllListeners()` is called from
within an event handler while a `removeListener` meta-listener is
registered
- Added undefined check before iterating over listeners array to match
Node.js behavior
- Added comprehensive regression tests

## Bug Description

When `removeAllListeners(type)` was called:
1. From within an event handler 
2. While a `removeListener` meta-listener was registered
3. For an event type with no listeners

It would crash with: `TypeError: undefined is not an object (evaluating
'this._events')`

## Root Cause

The `removeAllListeners` function tried to access `listeners.length`
without checking if `listeners` was defined first. When called with an
event type that had no listeners, `events[type]` returned `undefined`,
causing the crash.

## Fix

Added a check `if (listeners !== undefined)` before iterating, matching
the behavior in Node.js core:
https://github.com/nodejs/node/blob/main/lib/events.js#L768

## Test plan

-  Created regression test in `test/regression/issue/24147.test.ts`
-  Verified test fails with `USE_SYSTEM_BUN=1 bun test` (reproduces
bug)
-  Verified test passes with `bun bd test` (confirms fix)
-  Test covers the exact reproduction case from the issue
-  Additional tests for edge cases (actual listeners, nested calls)

🤖 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>
2025-10-28 12:32:15 -07:00
Jarred Sumner
523fc14d76 Deflake websocket test 2025-10-27 18:58:06 -07:00
Felipe Cardozo
a0a69ee146 fix: body already used error to throw TypeError (#24114)
Should fix https://github.com/oven-sh/bun/issues/24104

### What does this PR do?

This PR is changing `ERR_BODY_ALREADY_USED` to be TypeError instead of
Error.


### How did you verify your code works?
A test case added to verify that request call correctly throws a
TypeError after another request call on the same Request, confirming the
fix addresses the issue.

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2025-10-27 18:31:33 -07:00
robobun
668eba0eb8 fix(node:http): Fix ServerResponse.writableNeedDrain causing stream pause (#24137)
## Summary

Fixes #19111

This PR fixes a bug where `fs.createReadStream().pipe(ServerResponse)`
would fail to transfer data when ServerResponse had no handle
(standalone usage). This affected Vite's static file serving and other
middleware adapters using the connect-to-web pattern.

## Root Cause

The bug was in the `ServerResponse.writableNeedDrain` getter at line
1529 of `_http_server.ts`:

```typescript
return !this.destroyed && !this.finished && (this[kHandle]?.bufferedAmount ?? 1) !== 0;
```

When `ServerResponse` had no handle (which is common in middleware
scenarios), the nullish coalescing operator defaulted `bufferedAmount`
to **1** instead of **0**. This caused `writableNeedDrain` to always
return `true`.

## Impact

When `pipe()` checks `dest.writableNeedDrain === true`, it immediately
pauses the source stream to handle backpressure. With the bug,
standalone ServerResponse instances always appeared to need draining,
causing piped streams to pause and never resume.

## Fix

Changed the default value from `1` to `0`:

```typescript
return !this.destroyed && !this.finished && (this[kHandle]?.bufferedAmount ?? 0) !== 0;
```

## Test Plan

-  Added regression test in `test/regression/issue/19111.test.ts`
-  Verified fix with actual Vite middleware reproduction
-  Confirmed behavior matches Node.js

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>
2025-10-27 15:24:38 -07:00
Meghan Denny
64bfd8b938 Revert "deps: update elysia to 1.4.13" (#24133) 2025-10-27 12:49:41 -07:00
Jarred Sumner
b7ae21d0bc Mark flaky test as TODO 2025-10-26 14:29:31 -07:00
github-actions[bot]
4c00d8f016 deps: update elysia to 1.4.13 (#24085)
## What does this PR do?

Updates elysia to version 1.4.13

Compare: https://github.com/elysiajs/elysia/compare/1.4.12...1.4.13

Auto-updated by [this
workflow](https://github.com/oven-sh/bun/actions/workflows/update-vendor.yml)

Co-authored-by: Jarred-Sumner <709451+Jarred-Sumner@users.noreply.github.com>
2025-10-25 22:03:34 -07:00
SUZUKI Sosuke
f4b6396eac Fix unhandled exception in JSC__JSPromise__wrap when resolving promise (#23961)
### What does this PR do?

Previously, `JSC__JSPromise__wrap` would call
`JSC::JSPromise::resolvedPromise(globalObject, result)` without checking
if an exception was thrown during promise resolution. This
could happen in certain edge cases, such as when the result value is a
thenable that triggers stack overflow, or when the promise resolution
mechanism itself encounters an error.
When such exceptions occurred, they would escape back to the Zig code,
causing the CatchScope assertion to fail with "ASSERTION FAILED:
Unexpected exception observed on thread"
instead of being properly handled.

This PR adds an exception check immediately after calling
`JSC::JSPromise::resolvedPromise()` and before the `RELEASE_AND_RETURN`
macro. If an exception is detected, the function
now clears it and returns a rejected promise with the exception value,
ensuring consistent error handling behavior. This matches the pattern
already used earlier in the function
for the initial function call exception handling.

### How did you verify your code works?

new and existing tests

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2025-10-24 21:36:33 -07:00
robobun
cfe561a083 fix: allow lifecycle hooks to accept options as second parameter (#24039)
## Summary

Fixes #23133

This PR fixes a bug where lifecycle hooks (`beforeAll`, `beforeEach`,
`afterAll`, `afterEach`) would throw an error when called with a
function and options object:

```typescript
beforeAll(() => {
  console.log("beforeAll")
}, { timeout: 10_000 })
```

Previously, this would throw: `error: beforeAll() expects a function as
the second argument`

## Root Cause

The issue was in `ScopeFunctions.parseArguments()` at
`src/bun.js/test/ScopeFunctions.zig:342`. When parsing two arguments, it
always treated them as `(description, callback)` instead of checking if
they could be `(callback, options)`.

## Solution

Updated the two-argument parsing logic to check if the first argument is
a function and the second is not a function. In that case, treat them as
`(callback, options)` instead of `(description, callback)`.

## Changes

- Modified `src/bun.js/test/ScopeFunctions.zig` to handle `(callback,
options)` case
- Added regression test at `test/regression/issue/23133.test.ts`

## Testing

 Verified the fix works with the reproduction case from the issue
 Added comprehensive regression test covering all lifecycle hooks with
both object and numeric timeout options
 All existing jest-hooks tests still pass
 Test fails with `USE_SYSTEM_BUN=1` and passes with the fixed build

🤖 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>
2025-10-24 19:30:43 -07:00
robobun
5a7b824091 fix(css): process color-scheme rules inside @layer blocks (#24034)
## Summary

Fixes #20689

Previously, `@layer` blocks were not being processed through the CSS
minifier, which meant that `color-scheme` properties inside `@layer`
blocks would not get the required `--buncss-light`/`--buncss-dark`
variable injections needed for browsers that don't support the
`light-dark()` function.

## Changes

- Implemented proper minification for `LayerBlockRule` in
`src/css/rules/rules.zig:218-221`
- Added recursive call to `minify()` on nested rules, matching the
behavior of other at-rules like `@media` and `@supports`
- Added comprehensive tests for `color-scheme` inside `@layer` blocks

## Test Plan

Added three new test cases in `test/js/bun/css/css.test.ts`:
1. Simple `@layer` with `color-scheme: dark`
2. Named layers (`@layer shm.colors`) with multiple rules
3. Anonymous `@layer` with `color-scheme: light dark` (generates media
query)

All tests pass:
```bash
bun bd test test/js/bun/css/css.test.ts -t "color-scheme"
```

## Before

```css
/* Input */
@layer shm.colors {
  body.theme-dark {
    color-scheme: dark;
  }
}

/* Output (broken - no variables) */
@layer shm.colors {
  body.theme-dark {
    color-scheme: dark;
  }
}
```

## After

```css
/* Input */
@layer shm.colors {
  body.theme-dark {
    color-scheme: dark;
  }
}

/* Output (fixed - variables injected) */
@layer shm.colors {
  body.theme-dark {
    --buncss-light: ;
    --buncss-dark: initial;
    color-scheme: dark;
  }
}
```

🤖 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>
2025-10-24 19:27:14 -07:00
robobun
a3f18b9e0e feat(test): implement onTestFinished hook for bun:test (#24038)
## Summary

Implements `onTestFinished()` for `bun:test`, which runs after all
`afterEach` hooks have completed.

## Implementation

- Added `onTestFinished` export to the test module in `jest.zig`
- Modified `genericHook` in `bun_test.zig` to handle `onTestFinished` as
a special case that:
  - Can only be called inside a test (not in describe blocks or preload)
  - Appends hooks at the very end of the execution sequence
- Added comprehensive tests covering basic ordering, multiple callbacks,
async callbacks, and interaction with other hooks

## Execution Order

When called inside a test:
1. Test body executes
2. `afterAll` hooks (if added inside the test)
3. `afterEach` hooks
4. `onTestFinished` hooks 

## Test Plan

-  All new tests pass with `bun bd test`
-  Tests correctly fail with `USE_SYSTEM_BUN=1` (feature not in
released version)
-  Verifies correct ordering with `afterEach`, `afterAll`, and multiple
`onTestFinished` calls
-  Tests async `onTestFinished` callbacks

🤖 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: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: pfg <pfg@pfg.pw>
2025-10-24 19:07:40 -07:00
Marko Vejnovic
e76570f452 feat(ENG-21362): Environment Variables Store (#23930) 2025-10-23 23:08:08 -07:00
SUZUKI Sosuke
d648547942 Fix segv when process.nextTick is overwritten (#23971)
### 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>
2025-10-23 22:16:01 -07:00
SUZUKI Sosuke
fb75e077a2 Add missing empty JSValue checking for Bun.cookieMap#delete (#23951)
### 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>
2025-10-23 13:14:36 -07:00
avarayr
24d9d642de ProxyTunnel: close-delimited responses via proxy cause ECONNRESET (#23719)
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>
2025-10-23 13:04:23 -07:00
robobun
066f706a99 Fix CSS view-transition pseudo-elements with class selectors (#23957) 2025-10-22 16:45:03 -07:00
robobun
0ad4e6af2d Fix Buffer.isEncoding('') to return false (#23968)
## 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>
2025-10-22 16:15:29 -07:00
SUZUKI Sosuke
06eea5213a Add missing exception check for ReadableStream (#23932)
### 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>
2025-10-21 18:19:34 -07:00
robobun
cd8043b76e Fix Bun.build() compile API to properly apply sourcemaps (#23916)
## 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>
2025-10-21 14:25:08 -07:00
Dylan Conway
150338faab implement publicHoistPattern and hoistPattern (#23567)
### 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 #23481
closes #6160
closes #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>
2025-10-21 14:18:39 -07:00
Jarred Sumner
789a5f4078 Fix URL heap size reporting bug (#23887)
### 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>
2025-10-20 23:04:54 -07:00
pfg
7750afa29b Updates eqlComptime to resolve the rope if needed (#23883)
### What does this PR do?

Fixes #23723 

### How did you verify your code works?

Test case
2025-10-20 21:18:47 -07:00
robobun
3e53ada574 Fix assertion failure when using --production flag (#23821)
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>
2025-10-20 20:37:51 -07:00
Jarred Sumner
25a8dea38b Ensure we add sourcemappings for S.Comment (#23871)
### What does this PR do?



### How did you verify your code works?

---------

Co-authored-by: pfg <pfg@pfg.pw>
2025-10-20 20:36:25 -07:00
Dylan Conway
8b8e98d0fb fix(install): workspace self dependencies with isolated linker (#23609)
### 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>
2025-10-20 19:48:47 -07:00
robobun
b1f83d0bb2 fix: Response.json() throws TypeError for non-JSON serializable top-level values (#21258)
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: Meghan Denny <meghan@bun.com>
2025-10-20 19:46:22 -07:00
Meghan Denny
6dffd32d52 node: fix test-fs-promises-file-handle-readLines.mjs (#22399)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2025-10-20 19:39:10 -07:00
robobun
5971bf67ef fix: buffer allocation for path operations with very long paths (#23819)
## 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>
2025-10-20 19:28:34 -07:00
robobun
686998ed3d Fix panic when WebSocket close frame is fragmented across TCP packets (#23832)
## 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>
2025-10-20 18:42:19 -07:00
Jarred Sumner
b3c69e5a4e it's bun.com now 2025-10-20 18:01:25 -07:00
Ciro Spaciari
1e3e693f4a fix(MySQL) ref and status usage (#23873)
### 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>
2025-10-20 17:40:48 -07:00
robobun
2557b1cc2a Add email field support to .npmrc for registry authentication (#23709)
### 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>
2025-10-20 16:32:04 -07:00
robobun
ebc0cfeacd fix(yaml): double-quoted strings with '...' incorrectly trigger document end error (#23491)
### 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>
2025-10-20 14:19:22 -07:00
Jarred Sumner
abb85018df Fixes #23649 (#23853)
### What does this PR do?

Closes #23712
Fixes #23649
Fixes regression introduced in #19817

### How did you verify your code works?

Test
2025-10-20 14:07:31 -07:00
robobun
1c4d8b1c1c fix(sql): throw proper exception for invalid MySQL parameter types (#23839)
## 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>
2025-10-20 12:31:08 -07:00
robobun
3921f76ff8 Add --only-failures flag to bun:test (#23312)
## 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>
2025-10-19 23:31:29 -07:00
robobun
74fa49963c Fix: Error when using bun build --no-bundle with HTML entrypoint (#23572)
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>
2025-10-19 23:29:29 -07:00
Dylan Conway
fb2bf3fe83 fix(pack): always include bin even if not included by files (#23606)
### 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>
2025-10-19 23:28:59 -07:00
github-actions[bot]
6f3dfa79bb deps: update elysia to 1.4.12 (#23820)
## What does this PR do?

Updates elysia to version 1.4.12

Compare: https://github.com/elysiajs/elysia/compare/1.4.11...1.4.12

Auto-updated by [this
workflow](https://github.com/oven-sh/bun/actions/workflows/update-vendor.yml)

Co-authored-by: Jarred-Sumner <709451+Jarred-Sumner@users.noreply.github.com>
2025-10-19 22:25:50 -07:00
Jarred Sumner
767c61d355 Fix memory leaks & blocking syscall in Bun Shell (#23636)
## 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>
2025-10-19 22:17:19 -07:00
robobun
576b21f2ff fix(test): prevent integer overflow in pretty_format writeIndent (#23843)
## 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>
2025-10-19 21:20:56 -07:00
Dylan Conway
de4a5a07b1 fix(bundler): import.meta.url and esm wrapper fixes (#23803)
### 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>
2025-10-18 20:49:57 -07:00
Jarred Sumner
f912355587 Update process.test.js 2025-10-18 20:16:02 -07:00
Jarred Sumner
acefbe2421 Format + bump runtime transpiler cache version 2025-10-18 18:40:31 -07:00
taylor.fish
4a06991d3b Port SocketConfig to bindings generator (#23755)
(For internal tracking: fixes STAB-1471, STAB-1472, STAB-1473,
STAB-1474, STAB-1475, STAB-1476, STAB-1480, STAB-1481)

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Jarred Sumner <jarred@jarredsumner.com>
2025-10-18 18:14:01 -07:00
Jarred Sumner
74faec2cc9 Deflake test/js/bun/http/req-url-leak.test.ts 2025-10-18 18:08:08 -07:00