### 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?
### How did you verify your code works?
---------
Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude <noreply@anthropic.com>
<details>
<summary> observed in
https://buildkite.com/bun/bun/builds/22442#annotation-test/js/node/zlib/leak.test.ts
</summary>
```
==5045==ERROR: AddressSanitizer: heap-use-after-free on address 0x5220000243c0 at pc 0x00000dad671b bp 0x14f22d4a4990 sp 0x14f22d4a4988
READ of size 8 at 0x5220000243c0 thread T5 (HeapHelper)
======== Stack trace from GDB for HeapHelper-5045.core: ========
Program terminated with signal SIGABRT, Aborted.
#0 0x000014f2c3672eec in ?? () from /lib/x86_64-linux-gnu/libc.so.6
[Current thread is 1 (Thread 0x14f22d4f46c0 (LWP 5050))]
#0 0x000014f2c3672eec in ?? () from /lib/x86_64-linux-gnu/libc.so.6
#1 0x000014f2c3623fb2 in raise () from /lib/x86_64-linux-gnu/libc.so.6
#2 0x000014f2c360e472 in abort () from /lib/x86_64-linux-gnu/libc.so.6
#3 0x000000000e3b2ae2 in uw_init_context_1[cold] ()
#4 0x000000000e3b29fc in _Unwind_Backtrace ()
#5 0x00000000046a6bab in __sanitizer::BufferedStackTrace::UnwindSlow(unsigned long, unsigned int) ()
#6 0x00000000046a181d in __sanitizer::BufferedStackTrace::Unwind(unsigned int, unsigned long, unsigned long, void*, unsigned long, unsigned long, bool) ()
#7 0x00000000046885bd in __sanitizer::BufferedStackTrace::UnwindImpl(unsigned long, unsigned long, void*, bool, unsigned int) ()
#8 0x0000000004601127 in __asan::ErrorGeneric::Print() ()
#9 0x0000000004683180 in __asan::ScopedInErrorReport::~ScopedInErrorReport() ()
#10 0x0000000004686567 in __asan::ReportGenericError(unsigned long, unsigned long, unsigned long, unsigned long, bool, unsigned long, unsigned int, bool) ()
#11 0x0000000004686d46 in __asan_report_load8 ()
#12 0x000000000dad671b in ZSTD_sizeof_CCtx (cctx=<optimized out>) at ./build/release-asan/zstd/vendor/zstd/lib/compress/zstd_compress.c:210
#13 0x0000000006d2284d in bun.js.node.zlib.NativeZstd.estimatedSize () at /var/lib/buildkite-agent/builds/ip-172-31-72-121/bun/bun/src/bun.js/node/zlib/NativeZstd.zig:57
#14 ZigGeneratedClasses.JSNativeZstd.JavaScriptCoreBindings.NativeZstd__estimatedSize (thisValue=<optimized out>) at /var/lib/buildkite-agent/builds/ip-172-31-72-121/bun/bun/build/release-asan/codegen/ZigGeneratedClasses.zig:11122
#15 0x000000000852803b in WebCore::JSNativeZstd::visitChildrenImpl<JSC::SlotVisitor> (cell=0x14f22e190840, visitor=...) at ./build/release-asan/./build/release-asan/codegen/ZigGeneratedClasses.cpp:30728
#16 WebCore::JSNativeZstd::visitChildren (cell=0x14f22e190840, visitor=...) at ./build/release-asan/./build/release-asan/codegen/ZigGeneratedClasses.cpp:30734
#17 0x000000000aa99d6c in JSC::MethodTable::visitChildren (this=<optimized out>, cell=<optimized out>, visitor=...) at vendor/WebKit/Source/JavaScriptCore/runtime/ClassInfo.h:115
#18 0x000000000aa99d6c in JSC::SlotVisitor::visitChildren (this=0x14f277028300, cell=0x14f22e190840)
#19 JSC::SlotVisitor::drain(WTF::MonotonicTime)::$_0::operator()(JSC::MarkStackArray&) const (this=<optimized out>, stack=...) at vendor/WebKit/Source/JavaScriptCore/heap/SlotVisitor.cpp:509
#20 0x000000000aa8f130 in JSC::SlotVisitor::forEachMarkStack<JSC::SlotVisitor::drain(WTF::MonotonicTime)::$_0>(JSC::SlotVisitor::drain(WTF::MonotonicTime)::$_0 const&) (this=0x14f277028300, func=...) at vendor/WebKit/Source/JavaScriptCore/heap/SlotVisitorInlines.h:193
#21 JSC::SlotVisitor::drain (this=this@entry=0x14f277028300, timeout=<error reading variable: That operation is not available on integers of more than 8 bytes.>, timeout@entry=...) at vendor/WebKit/Source/JavaScriptCore/heap/SlotVisitor.cpp:499
#22 0x000000000aa90590 in JSC::SlotVisitor::drainFromShared (this=0x14f277028300, sharedDrainMode=JSC::SlotVisitor::HelperDrain, timeout=<error reading variable: That operation is not available on integers of more than 8 bytes.>) at vendor/WebKit/Source/JavaScriptCore/heap/SlotVisitor.cpp:699
#23 0x000000000aa08726 in JSC::Heap::runBeginPhase(JSC::GCConductor)::$_1::operator()() const (this=<optimized out>) at vendor/WebKit/Source/JavaScriptCore/heap/Heap.cpp:1508
#24 WTF::SharedTaskFunctor<void (), JSC::Heap::runBeginPhase(JSC::GCConductor)::$_1>::run() (this=<optimized out>) at .WTF/Headers/wtf/SharedTask.h:91
#25 0x000000000aa3b596 in WTF::ParallelHelperClient::runTask(WTF::RefPtr<WTF::SharedTask<void ()>, WTF::RawPtrTraits<WTF::SharedTask<void ()> >, WTF::DefaultRefDerefTraits<WTF::SharedTask<void ()> > > const&) (this=0x14f22e000428, task=...) at vendor/WebKit/Source/WTF/wtf/ParallelHelperPool.cpp:110
#26 0x000000000aa3d976 in WTF::ParallelHelperPool::Thread::work (this=<optimized out>) at vendor/WebKit/Source/WTF/wtf/ParallelHelperPool.cpp:201
#27 0x000000000aa4210d in WTF::AutomaticThread::start(WTF::AbstractLocker const&)::$_0::operator()() const (this=<optimized out>) at vendor/WebKit/Source/WTF/wtf/AutomaticThread.cpp:225
#28 WTF::Detail::CallableWrapper<WTF::AutomaticThread::start(WTF::AbstractLocker const&)::$_0, void>::call() (this=<optimized out>) at vendor/WebKit/Source/WTF/wtf/Function.h:53
#29 0x0000000008958ada in WTF::Function<void ()>::operator()() const (this=<optimized out>) at vendor/WebKit/Source/WTF/wtf/Function.h:82
#30 WTF::Thread::entryPoint (newThreadContext=<optimized out>) at vendor/WebKit/Source/WTF/wtf/Threading.cpp:272
#31 0x0000000008a65689 in WTF::wtfThreadEntryPoint (context=0x13b5) at vendor/WebKit/Source/WTF/wtf/posix/ThreadingPOSIX.cpp:255
#32 0x000000000467d347 in asan_thread_start(void*) ()
#33 0x000014f2c36711f5 in ?? () from /lib/x86_64-linux-gnu/libc.so.6
#34 0x000014f2c36f189c in ?? () from /lib/x86_64-linux-gnu/libc.so.6
```
</details>
`ZSTD_sizeof_CCtx` and `ZSTD_sizeof_DCtx` can not be relied upon to be
thread-safe and estimatedSize may be called from any thread
### What does this PR do?
After 10s of inactivity in the thread pool, this releases memory more
aggressively back to the operating system
### How did you verify your code works?
### 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
Fixes a bug in napi_get_value_bigint_words where the function would
return the number of words copied instead of the actual word count
needed when the provided buffer is smaller than required.
## The Problem
When napi_get_value_bigint_words was called with a buffer smaller than
the actual BigInt size, it would incorrectly return the buffer size
instead of the actual word count needed. This doesn't match Node.js
behavior.
### Example
BigInt that requires 2 words: 0x123456789ABCDEF0123456789ABCDEFn
Call with buffer for only 1 word
- Before fix: word_count = 1 (buffer size)
- After fix: word_count = 2 (actual words needed)
## The Fix
Changed napi_get_value_bigint_words to always set word_count to the
actual number of words in the BigInt, regardless of buffer size.
## Test Plan
- Added test test_bigint_word_count that verifies the word count is
correctly returned
- Added test test_ref_unref_underflow for the existing
napi_reference_unref underflow protection
- Both tests pass with the fix and match Node.js behavior
🤖 Generated with [Claude Code](https://claude.ai/code)
---------
Co-authored-by: Claude <noreply@anthropic.com>
### What does this PR do?
Removes the unused `capturedError` fixing the oxlint error. This
variable is never assigned to, hence the block on L1094 can never run.
### How did you verify your code works?
Existing tests
### What does this PR do?
It is easy to confuse `lines` and `columns` fields in `LineColumnOffset`
struct inside of `src/sourcemap/sourcemap.zig` as being either one or
zero based. The sourcemap spec says line and column offsets are zero
based. There was a place that was incorrectly assuming it was one based.
This PR switches it to use `bun.Ordinal` instead of bare `u32` integers
to prevent bugs and from this happening again.
### What does this PR do?
The `then` function in `transpiler.transform` can cause GC, which means
it can cause the `Transpiler` to become freed, which means that if that
same transpiler is in use by another run on the other thread, it could
have pointers to invalid memory.
Also, `ESMCondition` has unnecesasry memory allocations and there is a
very tiny memory leak in optionsFromLoaders
### How did you verify your code works?
Existing tests
---------
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
### What does this PR do?
Removes `DevServer.relative_path_buf` field and replaces it with usages
of `bun.path_buffer_pool` which is better than this debug lock thing
going on
---------
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Splits up js_parser.zig into multiple files. Also changes visitExprInOut
to use function calls rather than switch
Not ready:
- [ ] P.zig is ~70,000 tokens, still needs to get smaller
- [x] ~~measure zig build time before & after (is it slower?)~~ no
significant impact
---------
Co-authored-by: pfgithub <6010774+pfgithub@users.noreply.github.com>
Fixes#21189
`.pause()` should unref but it should still continue to emit `readable`
events (although it should not send `data` events)
also stdin.unref() should not pause input, it should only prevent stdin
from keeping the process alive.
DRAFT:
- [x] ~~this causes a bug where `process.stdin.on("readable", () => {});
process.stdin.pause()` will allow the process to exit when it
shouldn't.~~ fixed
---------
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
### What does this PR do?
We should not call .deinit() after .toJS otherwise hasPendingActivity
will access invalid memory
### How did you verify your code works?
Test run it with debug build on macos or asan on and will catch it
---------
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
### What does this PR do?
The DevSever's `IncrementalGraph` uses a data-oriented design memory
management style, storing data in lists and using indices instead of
pointers.
In conventional memory management, when we free a pointer and
accidentally use it will trip up asan. Obviously this doesn't apply when
using lists and indices, so this PR adds a check in debug & asan builds.
Everytime we free an `Edge` we better make sure that there are no more
dangling references to that spot.
This caught a case where we weren't setting `g.first_import[file_index]
= .none` when deleting a file's imports, causing a dangling reference
and out of bounds access.
---------
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
### What does this PR do?
dropAllLocks causes Thread::yield several times which means more system
calls which means more thread switches which means slower
### How did you verify your code works?
### What does this PR do?
Releasing heap access causes all the heap helper threads to wake up and
lock and then unlock futexes, but it's important to do that to ensure
finalizers run quickly.
That means releasing heap access is a balance between:
1. CPU usage
2. Memory usage
Not releasing heap access causes benchmarks like
https://github.com/oven-sh/bun/pull/14885 to regress due to finalizers
not being called quickly enough.
Releasing heap access too often causes high idle CPU usage.
For the following code:
```
setTimeout(() => {}, 10 * 1000)
```
command time -v when with defaultRemainingRunsUntilSkipReleaseAccess =
0:
>
> Involuntary context switches: 605
>
command time -v when with defaultRemainingRunsUntilSkipReleaseAccess =
5:
>
> Involuntary context switches: 350
>
command time -v when with defaultRemainingRunsUntilSkipReleaseAccess =
10:
>
> Involuntary context switches: 241
>
Also comapre the #14885 benchmark with different values.
The idea here is if you entered JS "recently", running any
finalizers that might've been waiting to be run is a good idea.
But if you haven't, like if the process is just waiting on I/O
then don't bother.
### How did you verify your code works?
### What does this PR do?
Instead of holding a strong for the options object passed with the
handlers, we make each of the callbacks kept alive by the handlers and
it detaches once the detachFromJS function is called.
This should fix#21570, which looks like it was caused by wrapper
functions for AsyncLocalStorage getting collected prematurely.
fixes#21254fixes#21553fixes#21422
### How did you verify your code works?
Ran test/js/node/http2/node-http2.test.js
## Summary
This PR optimizes the uSockets sweep timer to only run when there are
active connections that need timeout checking, rather than running
continuously even when no connections exist.
**Problem**: The sweep timer was running every 4 seconds
(LIBUS_TIMEOUT_GRANULARITY) regardless of whether there were any active
connections, causing unnecessary CPU usage when Bun applications are
idle.
**Solution**: Implement reference counting for active sockets so the
timer is only enabled when needed.
## Changes
- **Add sweep_timer_count field** to both C and Zig loop data structures
- **Implement helper functions** `us_internal_enable_sweep_timer()` and
`us_internal_disable_sweep_timer()`
- **Timer lifecycle management**:
- Timer starts disabled when loop is initialized
- Timer enables when first socket is linked (count 0→1)
- Timer disables when last socket is unlinked (count 1→0)
- **Socket coverage**: Applied to both regular sockets and connecting
sockets that need timeout sweeping
- **Listen socket exclusion**: Listen sockets don't increment the
counter as they don't need timeout checking
## Files Modified
- `packages/bun-usockets/src/internal/loop_data.h` - Added
sweep_timer_count field
- `src/deps/uws/InternalLoopData.zig` - Updated Zig struct to match C
struct
- `packages/bun-usockets/src/loop.c` - Helper functions and
initialization
- `packages/bun-usockets/src/internal/internal.h` - Function
declarations
- `packages/bun-usockets/src/context.c` - Socket link/unlink
modifications
## Test Results
Verified the optimization works correctly:
1. **✅ No timer during idle**: 5-second idle test showed no sweep timer
activity
2. **✅ Timer activates with connections**: Timer enables when server
starts listening
3. **✅ Timer runs periodically**: Sweep timer callbacks occur every ~4
seconds when connections are active
4. **✅ Timer deactivates**: Timer disables when connections are closed
## Performance Impact
This change significantly reduces CPU usage for idle Bun applications
with no active HTTP connections by eliminating unnecessary timer
callbacks. The optimization maintains all existing timeout functionality
while only running the sweep when actually needed.
## Test plan
- [x] Verify no timer activity during idle periods
- [x] Verify timer enables when connections are created
- [x] Verify timer runs at expected intervals when active
- [x] Verify timer disables when connections are closed
- [x] Test with HTTP server scenarios
- [ ] Run existing HTTP server test suite to ensure no regressions
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude <noreply@anthropic.com>
### What does this PR do?
Add missing check for .write() on a data-backed blob
### How did you verify your code works?
There is a test
---------
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Alistair Smith <hi@alistair.sh>
Previously it accepted `property: anytype` but now it's `[]const u8`
because that was the only allowed value, so it makes it easier to see
what type it accepts in autocomplete.
Also updates the doc comment, switches it to use ZIG_EXPORT, and updates
the cppbind doc comment
Fixes#7569
This adds expectTypeOf, but not the experimental `--typecheck` flag from
vitest. To use it, you need to typecheck manually with `bunx tsc
--noEmit` in addition to `bun test`
---------
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
### What does this PR do?
Fix: https://github.com/oven-sh/bun/issues/21351
Relevant changes:
Fix advance to properly cleanup success and failed queries that could be
still be in the queue
Always ref before executing
Use stronger atomics for ref/deref and hasPendingActivity
Fallback when thisValue is freed/null/zero and check if vm is being
shutdown
The bug in --hot in `resolveRopeIfNeeded` Issue is not meant to be fixed
in this PR this is a fix for the postgres regression
Added assertions so this bug is easier to catch on CI
### How did you verify your code works?
Test added
---------
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
### What does this PR do?
Resolves
```js
Bun v1.2.13 ([64ed68c](64ed68c9e0)) on windows x86_64 [TestCommand]
panic: ComptimeStringMap.fromJS: input is not a string
[comptime_string_map.zig:268](64ed68c9e0/src/comptime_string_map.zig (L268)): getWithEql
[Response.zig:682](64ed68c9e0/src/bun.js/webcore/Response.zig (L682)): init
[Request.zig:679](64ed68c9e0/src/bun.js/webcore/Request.zig (L679)): constructInto
[ZigGeneratedClasses.cpp:37976](64ed68c9e0/C:/buildkite-agent/builds/EC2AMAZ-Q4V5GV4/bun/bun/build/release/codegen/ZigGeneratedClasses.cpp#L37976): WebCore::JSRequestConstructor::construct
2 unknown/js code
llint_entry
Features: tsconfig, Bun.stdout, dotenv, jsc
```
### How did you verify your code works?
There is a test.
Before:
```
failing-test-passes.fixture.ts:
^ this test is marked as failing but it passed. Remove \`.failing\` if tested behavior now works
(fail) This should fail but it doesnt [0.24ms]
^ this test is marked as failing but it passed. Remove \`.failing\` if tested behavior now works
(fail) This should fail but it doesnt (async) [0.23ms]
```
After:
```
failing-test-passes.fixture.ts:
(fail) This should fail but it doesnt [0.24ms]
^ this test is marked as failing but it passed. Remove \`.failing\` if tested behavior now works
(fail) This should fail but it doesnt (async) [0.23ms]
^ this test is marked as failing but it passed. Remove \`.failing\` if tested behavior now works
```
Adds a snapshot test
---------
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
### What does this PR do?
if you spam the refresh button in `next dev`, we print this error:
```
⨯ Error: Stream is already ended
at writeHead (null)
at <anonymous> (null)
at <anonymous> (null)
at <anonymous> (null)
at <anonymous> (null)
at <anonymous> (null)
at <anonymous> (null)
at <anonymous> (null)
at processTicksAndRejections (null) {
digest: '2259044225',
code: 'ERR_STREAM_ALREADY_FINISHED',
toString: [Function: toString]
}
⨯ Error: failed to pipe response
at processTicksAndRejections (unknown:7:39) {
[cause]: Error: Stream is already ended
at writeHead (null)
at <anonymous> (null)
at <anonymous> (null)
at <anonymous> (null)
at <anonymous> (null)
at <anonymous> (null)
at <anonymous> (null)
at <anonymous> (null)
at processTicksAndRejections (null) {
digest: '2259044225',
code: 'ERR_STREAM_ALREADY_FINISHED',
toString: [Function: toString]
}
}
⨯ Error: failed to pipe response
at processTicksAndRejections (unknown:7:39) {
page: '/',
[cause]: Error: Stream is already ended
at writeHead (null)
at <anonymous> (null)
at <anonymous> (null)
at <anonymous> (null)
at <anonymous> (null)
at <anonymous> (null)
at <anonymous> (null)
at <anonymous> (null)
at processTicksAndRejections (null) {
digest: '2259044225',
code: 'ERR_STREAM_ALREADY_FINISHED',
toString: [Function: toString]
}
}
```
If the socket is already closed when writeHead is called, we're supposed
to silently ignore it instead of throwing an error . The close event is
supposed to be emitted on the next tick. Now, I think there are also
cases where we do not emit the close event which is similarly bad.
### How did you verify your code works?
Need to go through the node http server tests and see if any new ones
pass. Also maybe some will fail on this PR, let's see.
### What does this PR do?
We had `bun.strings.assertIsValidWindowsPath(...)` in the resolver, but
we can't do this because the path may come from the user. Instead, let
our error handling code handle it.
Also fixes#21065
---------
Co-authored-by: Jarred Sumner <jarred@jarredsumner.com>