You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
b2e40a feat: filter path suggestions by file type in HTML attributes (#218)
feat: filter path suggestions by file type in HTML attributes
Implements intelligent file filtering for HTML path completion based on
tag type and attributes. Files matching the expected type are now
prioritized in autocomplete suggestions.
Changes:
Add optional 'attributes' field to HtmlAttributeValueContext interface
Pass node attributes to completion participants in htmlCompletion
Implement getExtensionFilter() method in pathCompletion
Use sortText to prioritize matching files (0_) over others (1_)
28e96e Add setting to disable end tag suggestions (#219)
Add setting to disable end tag suggestions
Fixes #216
This change introduces a new hideEndTagSuggestions configuration option
in the CompletionConfiguration interface that allows users to disable
closing tag suggestions in HTML completions.
Previously, the html.suggest.html5 setting controlled whether HTML5
tags, properties, and values were suggested, but it did not affect
closing tag suggestions (e.g., </div>). Users who wanted to disable
the extension's suggestions entirely had no way to turn off these
end tag completions without disabling the entire extension.
Changes:
Added hideEndTagSuggestions?: boolean to the CompletionConfiguration
interface in htmlLanguageTypes.ts
Updated the collectCloseTagSuggestions function in htmlCompletion.ts
to check this setting and return early if end tag suggestions are
disabled
Added comprehensive tests to verify the setting works correctly in
various scenarios
The setting defaults to false (showing end tag suggestions) to
maintain backward compatibility with existing behavior.
Signed-off-by: Giovanni Magliocchetti <giovimag123@gmail.com>
add 5.6.0 entry for CompletionConfiguration.hideEndTagSuggestions
Signed-off-by: Giovanni Magliocchetti <giovimag123@gmail.com>
Co-authored-by: Martin Aeschlimann <martinae@microsoft.com>
6d8c8c doc[README.md]: add notes about syntax highlighting and web-data source near API section (#220)
616501 fix(buffer): prevent heap read-after-free in indexOf via valueOf-triggered detachment (#26927)
Summary
Fix a heap read-after-free vulnerability in Buffer.indexOf, Buffer.lastIndexOf, and Buffer.includes where the raw typedVector
pointer was cached before calling toNumber() on the byteOffset
argument. A user-supplied valueOf() callback could call ArrayBuffer.prototype.transfer() to detach the underlying ArrayBuffer, freeing the original memory, causing these methods to
scan freed heap data.
The fix defers fetching the typedVector pointer until after toNumber() completes, adds a detachment check, and throws a TypeError if the buffer was detached.
Test plan
New test file test/js/node/buffer-indexOf-detach.test.ts with 7
test cases:
indexOf throws TypeError when buffer detached via valueOf
lastIndexOf throws TypeError when buffer detached via valueOf
includes throws TypeError when buffer detached via valueOf
indexOf with string value throws TypeError when buffer detached
indexOf with Buffer value throws TypeError when buffer detached
Normal indexOf/lastIndexOf/includes functionality still works
indexOf with non-detaching valueOf still works correctly
All 7 tests pass with bun bd test
The 5 detachment tests fail with USE_SYSTEM_BUN=1 (confirming
they test the fix)
Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Jarred Sumner <jarred@jarredsumner.com>
2cae6c fix(tls): getPeerCertificate returns {} instead of undefined when no cert (#27135)
Summary
Closes #24374.
getPeerCertificate() now returns {} when a TLS handle exists
but no peer certificate is available (matching Node.js behavior).
Previously it returned undefined, which caused checkServerIdentity()
to crash during TLS handshakes.
Added null guard in both TLS handshake code paths in net.ts
before calling checkServerIdentity(), as a defensive measure against null (returned when no handle exists).
This fixes the TypeError: Cannot destructure property 'subject' from null or undefined value crash reported when connecting to MongoDB Atlas
clusters.
Test plan
New regression test in test/regression/issue/24374.test.ts
verifying:
getPeerCertificate() returns {} (not undefined) when no client
cert is presented
getPeerCertificate() returns null when no handle is available
checkServerIdentity() does not crash with an empty cert object
TLS handshake with checkServerIdentity callback works without
crashing
Verified test fails with system Bun (2 of 4 tests fail) and passes
with debug build (4/4 pass)
Existing TLS tests (node-tls-cert.test.ts) continue to pass
Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Jarred Sumner <jarred@jarredsumner.com>
04eaa6 fix(path): buffer overflow in resolve/relative when CWD + paths > PATH_SIZE (#27661)
Summary
Fixed heap buffer overflow in path.resolve, path.relative, and path.toNamespacedPath that occurred when the CWD length + path
argument lengths exceeded PATH_SIZE (4096 on Linux, 1024 on macOS)
The work buffers were sized for user-provided paths but didn't account
for the CWD that resolvePosixT/resolveWindowsT prepends when all
paths are relative
This caused non-deterministic segfaults (often in a later unrelated
allocation like path.normalize) because path string data overwrote
mimalloc's internal heap metadata
New test: test/js/node/path/resolve-long-cwd.test.ts — creates a
deep directory (~3000 bytes) and calls resolve/relative with long
relative paths, verifying correct output
Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
3101b8 harden(ws): validate Sec-WebSocket-Accept during handshake (#27504)
Summary
Implement RFC 6455 §4.2.2 compliant validation of the Sec-WebSocket-Accept header during WebSocket upgrade handshake
Previously the client checked that the header was present and
non-empty but did not verify the value matched base64(SHA-1(Sec-WebSocket-Key + GUID))
This hardens the handshake against intermediaries that may incorrectly
serve stale or mismatched 101 responses, ensuring the client only
proceeds when the server has actually acknowledged this specific upgrade
request
The mismatch_websocket_accept_header error code was already defined
but never emitted — it is now used
Test plan
New test: websocket-accept-header-validation.test.ts
Verifies incorrect Sec-WebSocket-Accept value causes connection
failure
Verifies correct Sec-WebSocket-Accept value allows successful
connection
Test validated with USE_SYSTEM_BUN=1 (fails on rejection test,
confirming the fix is necessary)
All existing WebSocket tests continue to pass (short-read,
subprotocol, close-fragmented, pong-fragmented, permessage-deflate)
Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Jarred Sumner <jarred@jarredsumner.com>
226d26 Revert "fix(bundler): default import from 'bun' with --bytecode no longer undefined (#27175)"
This reverts commit 87deb0e98e1cebb09a7531cd38d237aadd86284a.
87deb0 fix(bundler): default import from 'bun' with --bytecode no longer undefined (#27175)
Summary
Fixes import Bun from 'bun' being undefined when bundled with --bytecode flag
The CJS lowering pass was incorrectly adding .default property
access to globalThis.Bun, which doesn't have a default property
Also skips unnecessary __toESM wrapper inclusion for built-in bun
module imports
Root Cause
When --bytecode is used, the bundler wraps output in CJS format. For
external modules, the linker sets up a namespace_alias with alias: "default" so the printer generates property access like require_module().default. The printer correctly replaces the bun
import source with globalThis.Bun, but was still appending .default
— producing import_bun.default instead of just import_bun.
Fix
Three targeted changes:
scanImportsAndExports.zig: Skip CJS interop wrapping
(__toESM) for bun tagged imports since globalThis.Bun doesn't need
it
LinkerContext.zig: Pass import_record_index through to namespace_alias so the printer can identify the import source
js_printer.zig: Skip the .default property access for bun
tagged import records, while preserving named property accesses (e.g. .serve)
Test plan
bun bd test test/regression/issue/20670.test.ts — 4 pass
(default, aliased, combined, namespace imports)
Tests fail with USE_SYSTEM_BUN=1 confirming they test the actual
fix
bun bd test test/bundler/bundler_bun.test.ts — 10 pass
bun bd test test/bundler/bundler_cjs.test.ts — 23 pass
bun bd test test/bundler/bundler_edgecase.test.ts — 99 pass
Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: Jarred Sumner <jarred@jarredsumner.com>
9c085c fix(lockfile): handle BrokenPipe gracefully when printing lockfile (#26484)
Summary
Fixes bun bun.lockb | head showing an internal error message instead
of exiting silently
Test plan
Added regression test in test/regression/issue/05828.test.ts
Verified the test fails with the current release version
Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
547925 fix(cli): bun update -i select all ('A') now updates packages correctly (#26658)
Summary
Fixes the bug where pressing 'A' to select all packages in bun update -i would show "Selected X packages to update" but then immediately show
"No packages selected for update"
The issue was that packages where current_version == update_version
(already at the highest version within their semver constraint) but current_version != latest_version were silently skipped
The fix applies the same logic as the spacebar handler: when selecting
all packages with 'A', automatically set use_latest=true for packages
that need it
Test plan
Verified test fails with system Bun (demonstrates the bug exists)
Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude <noreply@anthropic.com>
cda1e9 fix(napi): allow structuredClone on napi_create_object results (#27444)
What does this PR do?
Fixes #25658 — structuredClone() throwing DataCloneError on objects
created via napi_create_object, which works in Node.js.
Root cause
Bun's napi_create_object creates a NapiPrototype (a JSDestructibleObject subclass with an inline napiRef field for fast napi_wrap/napi_unwrap), not a plain JSFinalObject.
WebKit's SerializedScriptValue serializer checks:
if (inObject->classInfo() != JSFinalObject::info())
return SerializationReturnCode::DataCloneError;
NapiPrototype has its own ClassInfo, so the check fails.
Node.js uses v8::Object::New() which creates a truly plain V8 object —
V8's serializer clones it fine.
Fix
Add NapiPrototype::info() to the serializer's allowlist. The inline napiRef C++ field is invisible to property enumeration (serializer
uses getOwnPropertyNames with PrivateSymbolMode::Exclude), so cloned
objects correctly contain only JS properties — matching Node.js, where napi_unwrap on a clone also fails.
How did you verify your code works?
Added test_napi_create_object_structured_clone using checkSameOutput which runs on both Node and Bun and asserts identical
output
Verified test fails with USE_SYSTEM_BUN=1 (throws DataCloneError)
Verified test passes with bun bd test
Verified existing test/js/web/workers/structured-clone.test.ts still
passes (118 tests)
924586 fix(http2): send connection-level WINDOW_UPDATE in setLocalWindowSize (#26917)
Summary
setLocalWindowSize() updated the internal connection window size but
never sent a WINDOW_UPDATE frame for stream 0 (connection level) to
the peer
Per RFC 9113 Section 6.9, INITIAL_WINDOW_SIZE only applies to
stream-level windows; the connection-level window must be updated
explicitly via WINDOW_UPDATE
This caused HTTP/2 streams to stall after receiving 65,535 bytes (the
default connection window), even when setLocalWindowSize() was called
with a larger value
Test plan
Added regression test test/regression/issue/26915.test.ts that
streams 256 KB over HTTP/2 with an enlarged window
Verified test fails with system bun (times out at 65,535
bytes)
Verified test passes with debug build containing the fix
Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude <noreply@anthropic.com>
850139 fix(zlib): validate buffer bounds in native write/writeSync instead of using assert (#26946)
Summary
Fixes OOB read/write vulnerability in native zlib handle write() and writeSync() methods where user-controlled in_off, in_len, out_off, out_len parameters were only validated via bun.assert(),
which compiles to a no-op in ReleaseFast production builds
Replaces all bun.assert() calls in both write() and writeSync()
with proper error returns (ERR_OUT_OF_RANGE, ERR_INVALID_ARG_TYPE, ERR_INVALID_ARG_VALUE, ERR_INVALID_STATE) that throw back to
JavaScript
Also hardens .? (forced unwrap) on asArrayBuffer() calls to use orelse with proper error messages
Test plan
Added test/js/node/zlib/zlib-handle-bounds-check.test.ts with 7
test cases:
Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
4de50d Revert "fix: don't call direct ReadableStream cancel on normal completion (#27214)"
This reverts commit 32230cc0b9ca312a7d6d158400f13c08621df2b0.
32230c fix: don't call direct ReadableStream cancel on normal completion (#27214)
Summary
Fixed ReadableStream with type: "direct" incorrectly calling the
user's cancel callback on normal stream completion
The close callback in readDirectStream was unconditionally
invoking underlyingSource.cancel(reason) whenever the stream was
finalized, even on successful completion where reason is undefined
Now the cancel callback is only invoked when there is a truthy reason (an actual error), matching expected ReadableStream behavior
Closes #17175
Test plan
Added regression test test/regression/issue/17175.test.ts with 3
test cases:
Direct stream cancel not called on normal completion (single write +
flush)
Direct stream cancel not called with multiple writes
Direct stream cancel not called with explicit close()
Verified all 3 tests fail with system Bun (USE_SYSTEM_BUN=1) and
pass with debug build
Verified existing serve-direct-readable-stream.test.ts still
passes
Verified existing direct stream tests in serve.test.ts still
pass
Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude <noreply@anthropic.com>
bf5025 fix(test): show empty string keys in object diffs (#27166)
Summary
Fix bun test object diffs silently dropping properties with empty
string keys ("")
Fix console.log also dropping empty string keys when formatting
objects
Identifier::isEmpty() was returning true for both null identifiers
and empty string identifiers, causing forEachPropertyOrdered and forEachPropertyImpl to skip "" keys entirely
Root Cause
In src/bun.js/bindings/bindings.cpp, two property iteration functions
used property.isEmpty() to skip invalid identifiers. However, WTF::String::isEmpty() returns true for zero-length strings (like ""), not just null strings. This meant legitimate empty string
property keys were silently dropped during object formatting.
The fix replaces property.isEmpty() with property.isNull() to only
skip null identifiers, and removes a redundant key.len == 0 check.
Test plan
Added regression test test/regression/issue/18028.test.ts with 6
test cases
Verified test passes with bun bd test
Verified subprocess diff test fails with USE_SYSTEM_BUN=1
(unfixed bun)
Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude <noreply@anthropic.com>
1a86bd fix(s3): respect slice range in .stream() when offset is 0 (#27273)
Summary
Fixed downloadStream() in src/s3/client.zig to correctly construct
a Range header when offset == 0 and a size is specified
The same bug was previously fixed for downloadSlice() (used by .text()/.arrayBuffer()) in PR #16400, but the fix was never applied
to downloadStream()
Without this fix, s3file.slice(0, N).stream() ignores the slice
range and downloads the entire file
Root Cause
In the downloadStream() function, when building the HTTP Range header,
there was an early return if (offset == 0) break :brk null inside the if (size) block. This caused the Range header to be omitted when
offset was 0, even when a size was specified — meaning .slice(0, 1070).stream() would download the entire file.
Test plan
Added regression test at test/regression/issue/27272.test.ts
Added .slice().stream() tests (offset 0 and non-zero offset) to test/js/bun/s3/s3.test.ts
Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude <noreply@anthropic.com>
915749 fix(types): add missing contentEncoding to S3Options type definition (#27329)
Summary
Adds the missing contentEncoding property to the S3Options
TypeScript type definition in packages/bun-types/s3.d.ts
The runtime support for contentEncoding was added in PR #26149 but
the type definitions were not updated, causing TypeScript errors and
missing IDE autocompletion
Closes #27328
Test plan
Verify contentEncoding appears in S3Options interface
alongside contentDisposition
Existing runtime tests in test/js/bun/s3/s3.test.ts already
cover the runtime behavior
Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude <noreply@anthropic.com>
a39303 fix(crypto): clear OpenSSL error queue in TryParsePrivateKey (#27446)
Summary
A failed crypto.createPrivateKey() call (e.g. on an encrypted PEM
without a passphrase) left stale errors on the OpenSSL error queue,
causing subsequent unrelated createPrivateKey() calls to fail with
"Passphrase required for encrypted key"
Added ClearErrorOnReturn at the top of TryParsePrivateKey() in ncrypto.cpp to ensure the OpenSSL error queue is clean on both entry
and exit
This is consistent with how other functions like TryParsePublicKeyInner() and writePrivateKey() already handle the
error queue
Closes #27445
Test plan
Added regression test test/regression/issue/27445.test.ts that
reproduces the exact scenario from the issue
Verified test fails with system bun (USE_SYSTEM_BUN=1)
Verified test passes with debug build (bun bd test)
Ran full crypto.key-objects.test.ts suite (83 pass, 0 fail)
Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Jarred Sumner <jarred@jarredsumner.com>
9f88b3 fix(http): validate header names and values in writeEarlyHints (#26933)
Summary
Fix CRLF injection vulnerability in ServerResponse.prototype.writeEarlyHints where non-link header keys
and values were concatenated into the raw HTTP 103 response without
validation
Add validateHeaderName and validateHeaderValue checks (same ones
used by setHeader) before writing headers to the socket
Add tests verifying that CRLF injection in both header names and
values is rejected, and that valid headers still work
Test plan
bun bd test test/js/node/http/early-hints-crlf-injection.test.ts
— 3/3 pass
USE_SYSTEM_BUN=1 bun test test/js/node/http/early-hints-crlf-injection.test.ts — 2/3 fail
(confirms test catches the vulnerability)
Existing test-http-early-hints-invalid-argument.js still passes
Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude <noreply@anthropic.com>
488ef6 fix(docs): correct bcrypt rounds description from log10 to log2 (#27475)
Summary
Fix incorrect description of bcrypt cost parameter in hashing docs: log10 → log2
The bcrypt cost factor is a power-of-2 exponent (cost=10 means 2^10 =
1,024 rounds), confirmed by src/bun.js/api/crypto/PasswordObject.zig
which uses the value as rounds_log with valid range 4–31
Test plan
Documentation-only change, no code behavior affected
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.redirect.github.com>
Fix signed char comparison bug in uWS HttpParser.h that caused
bytes >= 0x80 to be stripped from HTTP header values on platforms where char is signed (x86_64 Linux, x86_64 macOS, ARM macOS)
Replace < 33 comparison with explicit checks for SP and HTAB per RFC
9110 Section 5.5
This also fixes a potential request smuggling vector where Transfer-Encoding: \xffchunked\xff would be interpreted as Transfer-Encoding: chunked
Closes #8893
Root Cause
In packages/bun-uws/src/HttpParser.h, the getHeaders function
trimmed whitespace from header values using:
while (headers->value.back() < 33) { ... }
std::string_view::back() returns char, which is signed on
x86_64. Bytes 0x80-0xFF are negative values (-128 to -1), all less than
33, so they were incorrectly stripped as whitespace.
Fix
Replace the numeric comparison with explicit OWS character checks:
This matches RFC 9110 Section 5.5 which defines OWS (Optional White
Space) as only SP and HTAB.
Test plan
Added regression test test/regression/issue/08893.test.ts that
sends raw HTTP requests with 0xFF bytes in header values and verifies
they are preserved
Added test that SP/HTAB trimming still works correctly
bun bd test test/regression/issue/08893.test.ts passes (2/2
tests)
Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Jarred Sumner <jarred@jarredsumner.com>
c5f0e4 fix(css): use correct physical property IDs for logical border-radius with var() (#27460)
Summary
Fixed CSS bundler incorrectly mapping all four logical border-radius
properties (border-start-start-radius, border-start-end-radius, border-end-start-radius, border-end-end-radius) to border-top-left-radius/border-top-right-radius when values contain var() references
The unparsed branch in BorderRadiusHandler.logicalProperty()
hardcoded property IDs instead of using the ltr/rtl comptime
parameters that are already correctly passed to the function
Closes #27458
Test plan
Added regression test in test/regression/issue/27458.test.ts
Test verifies all four distinct physical properties are present in
output
Test verifies each physical property appears exactly once per LTR
block
Test fails on system bun (USE_SYSTEM_BUN=1), passes on debug
build
Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude <noreply@anthropic.com>
106a95 fix(bundler): use absolute asset URLs in HTML for --compile mode (#27466)
Summary
When bun build --compile bundles HTML with JS/CSS assets, the client
transpiler's public_path was set to "" (empty), which caused cheapPrefixNormalizer to produce relative URLs like ./chunk-abc.js
These relative URLs break when HTML is served from nested routes (e.g. /foo/) because the browser resolves them relative to the current path
(producing /foo/chunk-abc.js instead of /chunk-abc.js)
Changed the client transpiler's public_path from "" to "/" so
assets use absolute root-relative URLs like /chunk-abc.js
Closes #27465
Test plan
Regression test in test/regression/issue/27465.test.ts verifies
compiled HTML serves assets with absolute URLs from nested routes
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Updated Packages