Skip to content

buffer: wrap negative ucs2 indexOf offset against raw byte length for Buffer needles - #34273

Merged
Jarred-Sumner merged 4 commits into
mainfrom
claude/farm/f3964c65/buffer-lastindexof-ucs2-odd-len
Jul 16, 2026
Merged

Jarred-Sumner merged 4 commits into
mainfrom
claude/farm/f3964c65/buffer-lastindexof-ucs2-odd-len

Conversation

@robobun

@robobun robobun commented Jul 15, 2026 •

Copy link
Copy Markdown
Collaborator

Reproduction

const h = Buffer.from("bbc", "latin1");  // <62 62 63>
const n = Buffer.from("bb", "latin1");   // <62 62>
h.lastIndexOf(n, -3, "ucs2");  // bun: -1, node: 0

On an odd-length haystack, byteOffset === -buf.length wrongly returns -1 for data that is present. The same applies to utf16le, to indexOf at certain offsets, and to the empty-needle clamp.

Cause

indexOfBuffer computed haystackLength = byteLength & ~1 for UTF-16 encodings and passed that to computeIndexOfRange, which wraps negative offsets as length + offset. With byteLength = 3, -3 + (3 & ~1) = -1 lands in the "before the start: no match" arm.

Node's IndexOfBuffer uses the raw byte length for IndexOfOffset and only floors to 16-bit units for the search itself. Node's IndexOfString, by contrast, does truncate the haystack length to even before IndexOfOffset. Bun was applying the string-needle behavior to both paths.

Fix

  • indexOfBuffer now passes the raw byteLength to computeIndexOfRange.
  • indexOfString keeps the even-truncated haystackLength (matching Node).
  • The searchEnd &= ~1 step moves inside computeIndexOfRange (via a new isUTF16 flag) so the empty-needle clamp uses the even-truncated search end, again matching Node.

Verification

bun bd test test/js/node/buffer.test.js (616 pass), test/js/node/buffer-indexOf-detach.test.ts (13 pass), and test/js/node/test/parallel/test-buffer-indexof.js all pass. A differential sweep over haystack lengths 0..7, needle lengths 0..4, offsets -(hlen+2)..hlen+2, both directions and both encoding names is byte-identical to Node v26.3.0.


[review] gate passed · iteration 2 · 2 files touched

fails on main (without fix)
ASAN without fix: 2 failed, 1 skipped
$ BUN_DEBUG_QUIET_LOGS=1 bun scripts/build.ts --profile=debug --quiet test "--reporter=junit" "--reporter-outfile=/tmp/mechgate.xml" test/js/node/buffer.test.js
info: syncing channel updates for nightly-2026-05-06-x86_64-unknown-linux-gnu
info: latest update on 2026-05-06 for version 1.97.0-nightly (e95e73209 2026-05-05)
info: component rust-src is up to date
info: checking for self-update (current version: 1.29.0)
bun test v1.4.0 (a3fa56257)

test/js/node/buffer.test.js:
(pass) with native Buffer.write > #9120 fill [89.53ms]
(pass) with native Buffer.write > #9120 alloc [59.77ms]
(pass) with native Buffer.write > isAscii [62.06ms]
(pass) with native Buffer.write > isUtf8 [60.99ms]
(pass) with native Buffer.write > Buffer global is settable [57.03ms]
(pass) with native Buffer.write > length overflow [58.77ms]
(pass) with native Buffer.write > truncate input values [238.62ms]
(pass) with native Buffer.write > Buffer.allocUnsafe() [56.03ms]
(pass) with native Buffer.write > Buffer.from() [58.58ms]
(pass) with native Buffer.write > offset properties [59.89ms]
(pass) with native Buffer.write > creating a Buffer from a Uint32Array [65.55ms]
(pass) with native Buffer.writ
... (truncated)

release without fix: all passed
bun test v1.4.0-canary.1 (0fe7a9039)

test/js/node/buffer.test.js:
(pass) with native Buffer.write > #9120 fill [2.61ms]
(pass) with native Buffer.write > #9120 alloc [2.08ms]
(pass) with native Buffer.write > isAscii [2.02ms]
(pass) with native Buffer.write > isUtf8 [2.04ms]
(pass) with native Buffer.write > Buffer global is settable [2.17ms]
(pass) with native Buffer.write > length overflow [2.86ms]
(pass) with native Buffer.write > truncate input values [2.60ms]
(pass) with native Buffer.write > Buffer.allocUnsafe() [2.07ms]
(pass) with native Buffer.write > Buffer.from() [2.19ms]
(pass) with native Buffer.write > offset properties [2.26ms]
(pass) with native Buffer.write > creating a Buffer from a Uint32Array [3.11ms]
(pass) with native Buffer.write > creating a Buffer from a Uint32Array (old constructor) [2.07ms]
(pass) with native Buffer.write > invalid encoding [2.23ms]
(pass) with native Buffer.write > create 0-length buffers [2.37ms]
(pass) with native Buffer.write > write() beyond end of buffer [2.73ms]
(pass) with native Buffer.write > write BigInt beyond 64-bit range [2.79ms]
(pass) with native Buffer.write > write BigInt64 with insufficient buffer space
... (truncated)
passes on PR (with fix)
ASAN with fix: 1 skipped
$ BUN_DEBUG_QUIET_LOGS=1 bun scripts/build.ts --profile=debug --quiet test "--reporter=junit" "--reporter-outfile=/tmp/mechgate.xml" test/js/node/buffer.test.js
info: syncing channel updates for nightly-2026-05-06-x86_64-unknown-linux-gnu
info: latest update on 2026-05-06 for version 1.97.0-nightly (e95e73209 2026-05-05)
info: component rust-src is up to date
info: checking for self-update (current version: 1.29.0)
bun test v1.4.0 (a3fa56257)

test/js/node/buffer.test.js:
(pass) with native Buffer.write > #9120 fill [83.11ms]
(pass) with native Buffer.write > #9120 alloc [58.77ms]
(pass) with native Buffer.write > isAscii [63.11ms]
(pass) with native Buffer.write > isUtf8 [68.71ms]
(pass) with native Buffer.write > Buffer global is settable [63.01ms]
(pass) with native Buffer.write > length overflow [62.05ms]
(pass) with native Buffer.write > truncate input values [247.18ms]
(pass) with native Buffer.write > Buffer.allocUnsafe() [58.54ms]
(pass) with native Buffer.write > Buffer.from() [64.59ms]
(pass) with native Buffer.write > offset properties [64.76ms]
(pass) with native Buffer.write > creating a Buffer from a Uint32Array [74.05ms]
(pass) with native Buffer.writ
... (truncated)

release with fix: all passed
$ bun scripts/build.ts --profile=release
info: syncing channel updates for nightly-2026-05-06-x86_64-unknown-linux-gnu
info: latest update on 2026-05-06 for version 1.97.0-nightly (e95e73209 2026-05-05)
info: component rust-src is up to date
info: checking for self-update (current version: 1.29.0)
[configured] bun-profile → bun (stripped) in 753ms (unchanged)
ninja: Entering directory `/workspace/bun/build/release'
[1/8] gen JSBuffer.lut.h
Generating /workspace/bun/build/release/codegen/JSBuffer.lut.h from /workspace/bun/src/jsc/bindings/JSBuffer.cpp
[2/8] gen cpp.rs (cppbind)
[2/8] cargo bun_bin → libbun_rust.a (--target x86_64-unknown-linux-gnu)
info: syncing channel updates for nightly-2026-05-06-x86_64-unknown-linux-gnu
info: latest update on 2026-05-06 for version 1.97.0-nightly (e95e73209 2026-05-05)
info: component rust-src is up to date
info: component rust-std is up to date

  nightly-2026-05-06-x86_64-unknown-linux-gnu unchanged - rustc 1.97.0-nightly (e95e73209 2026-05-05)

info: checking for self-update (current version: 1.29.0)
�[1m�[92m   Compiling�[0m bun_core v0.0.0 (/workspace/bun/src/bun_core)
�[1m�[92m   Compiling�[0m bun_errno v0.0.0 (/worksp
... (truncated)
diff hotspot
src/jsc/bindings/JSBuffer.cpp | 24 +++++++++++--------
 test/js/node/buffer.test.js   | 55 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 69 insertions(+), 10 deletions(-)

gate history · 3 passed · 0 rejected · iteration 2

evidence per changed file
file                           reads  edits  tests
src/jsc/bindings/JSBuffer.cpp      2      4      0
test/js/node/buffer.test.js        2      3      0

… Buffer needles

Buffer.prototype.lastIndexOf/indexOf with a Buffer needle and a ucs2/utf16le
encoding was truncating the haystack to an even byte length before wrapping a
negative byteOffset. On an odd-length haystack this makes byteOffset ===
-buf.length land one byte before the start and return -1 for data that is
present.

Node's IndexOfBuffer wraps negative offsets against the raw byte length and
only floors to 16-bit units when searching. IndexOfString, by contrast, does
truncate before the wrap; the previous code applied the string behavior to
both paths. Move the search-end even-truncation into computeIndexOfRange so
the empty-needle clamp also matches Node, and pass the raw byte length for
Buffer needles.
@coderabbitai

coderabbitai Bot commented Jul 15, 2026 •

Copy link
Copy Markdown
Contributor

Review Change Stack

Walkthrough

Changes

UTF-16 index range handling

Layer / File(s) Summary
Centralize UTF-16 search alignment
src/jsc/bindings/JSBuffer.cpp
computeIndexOfRange aligns UTF-16 search endpoints, and numeric, string, and Buffer search callers pass the corresponding encoding mode.
Validate negative-offset semantics
test/js/node/buffer.test.js
Tests cover UTF-16 searches with negative offsets, odd and even haystack lengths, and string or Buffer needles.

Suggested reviewers: jarred-sumner

🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title is concise and clearly describes the main Buffer negative-offset fix for UCS2 Buffer needles.
Description check ✅ Passed The description covers the problem, cause, fix, and verification, though it uses different headings than the template.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

Comment @coderabbitai help to get the list of available commands.

@robobun

robobun commented Jul 15, 2026 •

Copy link
Copy Markdown
Collaborator Author
Updated 5:27 PM PT - Jul 15th, 2026

❌ @robobun, your commit a3fa562 has 1 failures in Build #73447 (All Failures):


🧪   To try this PR locally:

bunx bun-pr 34273

That installs a local version of the PR into your bun-34273 executable, so you can run:

bun-34273 --bun

@claude claude Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Beyond the inline finding, I also checked: the indexOfString path is unaffected (it still passes the even-truncated haystackLength, so the new in-helper searchEnd &= ~1 is idempotent there), and the new empty-needle assertions (h3.lastIndexOf(empty, 3|undefined, 'ucs2') === 2) match Node's IndexOfBuffer — the raw-wrapped offset clamps against the even searchEnd.

Extended reasoning...

The confirmed regression in forward indexOf(Buffer, oddWrappedOffset, 'ucs2') is covered by the inline comment. Separately, I verified that indexOfString behavior is preserved (even-truncated haystackLength → & ~1 on searchEnd is a no-op) and that the new test's empty-Buffer-needle expectations on the odd-length haystack are Node-correct rather than locking in a divergence. indexOfNumber passes isUTF16=false and is untouched.

Comment thread src/jsc/bindings/JSBuffer.cpp

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@test/js/node/buffer.test.js`:
- Around line 2436-2445: Replace the encoding loop surrounding the eight Buffer
search assertions with a describe.each() parameterized test over "ucs2" and
"utf16le". Pass the selected encoding into the test case and preserve all
existing assertions and expected results while providing separate reporting for
each encoding.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: f48e2d86-9ae6-4170-a52e-71829c35ad00

📥 Commits

Reviewing files that changed from the base of the PR and between 591ade7 and 3d76c29.

📒 Files selected for processing (2)
  • src/jsc/bindings/JSBuffer.cpp
  • test/js/node/buffer.test.js

Comment thread test/js/node/buffer.test.js

@claude claude Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM — thanks for the empirical Node check on the -2 offset case; my earlier read of IndexOfBuffer was wrong and the added lock-in assertions cover it.

Re-traced computeIndexOfRange with the new isUTF16 flag through all three callers (indexOfNumber unaffected, indexOfString unchanged since it already passed the even-floored length, indexOfBuffer now wraps against raw byteLength). Checked that the empty-needle clamp and the forward needleLength + offset > searchEnd early-exit both see the even-floored searchEnd, matching Node's ordering. Walked the new test assertions (h3/h5/h1, Buffer vs. string needle, empty needle) against the post-PR arithmetic and they all line up.

Extended reasoning...

Overview

This PR fixes a Node.js compatibility bug in Buffer.prototype.indexOf/lastIndexOf with a Buffer needle and ucs2/utf16le encoding on odd-length haystacks. Previously indexOfBuffer floored byteLength to even before passing it to computeIndexOfRange, so a negative offset of exactly -byteLength wrapped to -1 and returned no-match for data that is present. Node's IndexOfBuffer wraps against the raw byte length and only floors to 16-bit units for the search itself; Node's IndexOfString does floor first. The fix threads an isUTF16 flag into computeIndexOfRange so searchEnd is even-floored there (used by both the empty-needle clamp and the forward-bound check), while indexOfBuffer now passes raw byteLength and indexOfString keeps the pre-floored length. indexOfNumber passes isUTF16=false and is unaffected. ~14 net lines in JSBuffer.cpp plus 54 lines of new tests.

Prior review

My earlier inline comment claimed h3.indexOf(n, -2, 'ucs2') should return 0 based on a misread of Node's source (I thought the forward-bound check used raw haystack_length). The author refuted this with a direct Node v26.3.0 run showing -1 and pointed to the actual line where Node floors search_end before that check. Commit 3d76c29 added expect(h3.indexOf(n, -2, enc)).toBe(-1) and the positive odd-offset case to lock the behavior in. I re-traced the post-PR path for that input and it returns -1 as Node does; the thread is correctly resolved.

Security risks

None. Pure integer offset arithmetic on already-bounds-checked buffer lengths; searchEnd is clamped to [0, haystackLength] before the & ~1, and the search helpers (indexOf16/lastIndexOf16) receive searchEnd ≤ byteLength. No new allocations, no user-controlled sizes flowing into pointer arithmetic beyond what was already there.

Level of scrutiny

Medium — native C++ offset arithmetic is easy to get subtly wrong (as my own earlier misread demonstrates), but the change is small, contained to three adjacent static functions, and the author ran a full differential sweep against Node v26.3.0 over haystack lengths 0..7 × needle lengths 0..4 × offsets -(hlen+2)..hlen+2 × both directions × both encoding names. That sweep plus the passing test-buffer-indexof.js port and 616 existing buffer.test.js cases is stronger evidence than manual tracing.

Other factors

All three call sites of computeIndexOfRange were updated for the new parameter. The new test covers the string-needle path explicitly to pin down that it stays on the even-truncated behavior (Node's documented divergence between IndexOfString and IndexOfBuffer). Evidence in the PR body shows the test fails on main (2 failures ASAN, 54 release) and passes with the fix. No CODEOWNERS entry for src/jsc/bindings/JSBuffer.cpp.

@robobun
robobun force-pushed the claude/farm/f3964c65/buffer-lastindexof-ucs2-odd-len branch from 07be021 to 0fe7a90 Compare July 15, 2026 21:09
Comment thread src/jsc/bindings/JSBuffer.cpp
@robobun

robobun commented Jul 15, 2026 •

Copy link
Copy Markdown
Collaborator Author

The diff is green: test/js/node/buffer.test.js passes on every lane across builds #73423, #73434, and #73447.

The remaining CI failures are unrelated to this change:

  • test-worker-message-port-transfer-terminate.js (x64-asan, builds 73423/73434): JSC exception-scope assertion during worker termination; passes 5/5 locally with this build, passed in 73447, and is being addressed separately.
  • test-net-connect-memleak.js (alpine x64, build 73447): marked pre-existing on main.
  • 30205.test.ts, test-fs-promises-file-handle-readFile.js, net-mongodb-pattern-leak.test.ts, test-repl-close.js, s3.test.ts, complex-workspace.test.ts, bun-install-registry.test.ts, fetch-tls-abortsignal-timeout.test.ts, hot.test.ts, webview-chrome.test.ts: marked flaky by the CI tooling (passed on retry) or external service unavailability.

None of these touch Buffer.prototype.indexOf/lastIndexOf or JSBuffer.cpp. Ready for review.

Comment thread test/js/node/buffer.test.js Outdated
@Jarred-Sumner
Jarred-Sumner merged commit af07712 into main Jul 16, 2026
77 of 78 checks passed
@Jarred-Sumner
Jarred-Sumner deleted the claude/farm/f3964c65/buffer-lastindexof-ucs2-odd-len branch July 16, 2026 05:29
hughescr added a commit to hughescr/bun that referenced this pull request Jul 16, 2026
* upstream/main: (57 commits)
  node:http/https/http2: raise Node v26.3.0 compat to ~94%, sync the upstream suites, and fix the Windows/macOS transport-layer teardown bugs they exposed (oven-sh#32488)
  expect: fix panic in toBeArrayOfSize/toHaveBeenCalledTimes with length > i32 max (oven-sh#32266)
  lexer: fix TOKEN_TO_STRING[TColon] showing " =" instead of ":" (oven-sh#34253)
  Bun.Terminal: write() returns bytes accepted, fire drain on POSIX (oven-sh#34289)
  test(serve-body-leak): give release-asan the same 60s per-test timeout as debug (oven-sh#34297)
  worker: mark the context terminating before the final concurrent-queue drain (oven-sh#34278)
  buffer: wrap negative ucs2 indexOf offset against raw byte length for Buffer needles (oven-sh#34273)
  fs.promises.watch: yield events with a null prototype (oven-sh#34279)
  child_process: latch stdin write EPIPE as 'error' + destroy, fail later writes with ERR_STREAM_DESTROYED (oven-sh#34268)
  Fix asString assertion when passing String objects as signals (oven-sh#34265)
  Buffer: carry size_t through toString/write so length 2^32 doesn't wrap to 0 (oven-sh#34274)
  test: use tempDir in log-test.test.ts instead of hardcoded /tmp path (oven-sh#34294)
  tty: track raw mode per handle instead of per process (oven-sh#33527)
  test: expect the bumped mimalloc SHA in process.versions
  Return freed memory to the OS on a background thread instead of the JS thread (oven-sh#34181)
  Move WTFTimer out of the shared timer heap to fix a cross-thread race (oven-sh#33131)
  test: update block-scoped enum lowering expectations to let (oven-sh#34287)
  Error.captureStackTrace: install .stack as non-enumerable (oven-sh#34259)
  js_parser: treat "async as T" / "async satisfies T" as a cast, not an arrow (oven-sh#34246)
  js_parser: accept `!`, `#name`, and `export @dec` in standard decorator grammar (oven-sh#34245)
  ...
hughescr added a commit to hughescr/bun that referenced this pull request Jul 16, 2026
* upstream/main: (70 commits)
  node:http/https/http2: raise Node v26.3.0 compat to ~94%, sync the upstream suites, and fix the Windows/macOS transport-layer teardown bugs they exposed (oven-sh#32488)
  expect: fix panic in toBeArrayOfSize/toHaveBeenCalledTimes with length > i32 max (oven-sh#32266)
  lexer: fix TOKEN_TO_STRING[TColon] showing " =" instead of ":" (oven-sh#34253)
  Bun.Terminal: write() returns bytes accepted, fire drain on POSIX (oven-sh#34289)
  test(serve-body-leak): give release-asan the same 60s per-test timeout as debug (oven-sh#34297)
  worker: mark the context terminating before the final concurrent-queue drain (oven-sh#34278)
  buffer: wrap negative ucs2 indexOf offset against raw byte length for Buffer needles (oven-sh#34273)
  fs.promises.watch: yield events with a null prototype (oven-sh#34279)
  child_process: latch stdin write EPIPE as 'error' + destroy, fail later writes with ERR_STREAM_DESTROYED (oven-sh#34268)
  Fix asString assertion when passing String objects as signals (oven-sh#34265)
  Buffer: carry size_t through toString/write so length 2^32 doesn't wrap to 0 (oven-sh#34274)
  test: use tempDir in log-test.test.ts instead of hardcoded /tmp path (oven-sh#34294)
  tty: track raw mode per handle instead of per process (oven-sh#33527)
  test: expect the bumped mimalloc SHA in process.versions
  Return freed memory to the OS on a background thread instead of the JS thread (oven-sh#34181)
  Move WTFTimer out of the shared timer heap to fix a cross-thread race (oven-sh#33131)
  test: update block-scoped enum lowering expectations to let (oven-sh#34287)
  Error.captureStackTrace: install .stack as non-enumerable (oven-sh#34259)
  js_parser: treat "async as T" / "async satisfies T" as a cast, not an arrow (oven-sh#34246)
  js_parser: accept `!`, `#name`, and `export @dec` in standard decorator grammar (oven-sh#34245)
  ...
hughescr added a commit to hughescr/bun that referenced this pull request Jul 16, 2026
* upstream/main: (52 commits)
  node:http/https/http2: raise Node v26.3.0 compat to ~94%, sync the upstream suites, and fix the Windows/macOS transport-layer teardown bugs they exposed (oven-sh#32488)
  expect: fix panic in toBeArrayOfSize/toHaveBeenCalledTimes with length > i32 max (oven-sh#32266)
  lexer: fix TOKEN_TO_STRING[TColon] showing " =" instead of ":" (oven-sh#34253)
  Bun.Terminal: write() returns bytes accepted, fire drain on POSIX (oven-sh#34289)
  test(serve-body-leak): give release-asan the same 60s per-test timeout as debug (oven-sh#34297)
  worker: mark the context terminating before the final concurrent-queue drain (oven-sh#34278)
  buffer: wrap negative ucs2 indexOf offset against raw byte length for Buffer needles (oven-sh#34273)
  fs.promises.watch: yield events with a null prototype (oven-sh#34279)
  child_process: latch stdin write EPIPE as 'error' + destroy, fail later writes with ERR_STREAM_DESTROYED (oven-sh#34268)
  Fix asString assertion when passing String objects as signals (oven-sh#34265)
  Buffer: carry size_t through toString/write so length 2^32 doesn't wrap to 0 (oven-sh#34274)
  test: use tempDir in log-test.test.ts instead of hardcoded /tmp path (oven-sh#34294)
  tty: track raw mode per handle instead of per process (oven-sh#33527)
  test: expect the bumped mimalloc SHA in process.versions
  Return freed memory to the OS on a background thread instead of the JS thread (oven-sh#34181)
  Move WTFTimer out of the shared timer heap to fix a cross-thread race (oven-sh#33131)
  test: update block-scoped enum lowering expectations to let (oven-sh#34287)
  Error.captureStackTrace: install .stack as non-enumerable (oven-sh#34259)
  js_parser: treat "async as T" / "async satisfies T" as a cast, not an arrow (oven-sh#34246)
  js_parser: accept `!`, `#name`, and `export @dec` in standard decorator grammar (oven-sh#34245)
  ...
hughescr added a commit to hughescr/bun that referenced this pull request Jul 16, 2026
* upstream/main: (52 commits)
  node:http/https/http2: raise Node v26.3.0 compat to ~94%, sync the upstream suites, and fix the Windows/macOS transport-layer teardown bugs they exposed (oven-sh#32488)
  expect: fix panic in toBeArrayOfSize/toHaveBeenCalledTimes with length > i32 max (oven-sh#32266)
  lexer: fix TOKEN_TO_STRING[TColon] showing " =" instead of ":" (oven-sh#34253)
  Bun.Terminal: write() returns bytes accepted, fire drain on POSIX (oven-sh#34289)
  test(serve-body-leak): give release-asan the same 60s per-test timeout as debug (oven-sh#34297)
  worker: mark the context terminating before the final concurrent-queue drain (oven-sh#34278)
  buffer: wrap negative ucs2 indexOf offset against raw byte length for Buffer needles (oven-sh#34273)
  fs.promises.watch: yield events with a null prototype (oven-sh#34279)
  child_process: latch stdin write EPIPE as 'error' + destroy, fail later writes with ERR_STREAM_DESTROYED (oven-sh#34268)
  Fix asString assertion when passing String objects as signals (oven-sh#34265)
  Buffer: carry size_t through toString/write so length 2^32 doesn't wrap to 0 (oven-sh#34274)
  test: use tempDir in log-test.test.ts instead of hardcoded /tmp path (oven-sh#34294)
  tty: track raw mode per handle instead of per process (oven-sh#33527)
  test: expect the bumped mimalloc SHA in process.versions
  Return freed memory to the OS on a background thread instead of the JS thread (oven-sh#34181)
  Move WTFTimer out of the shared timer heap to fix a cross-thread race (oven-sh#33131)
  test: update block-scoped enum lowering expectations to let (oven-sh#34287)
  Error.captureStackTrace: install .stack as non-enumerable (oven-sh#34259)
  js_parser: treat "async as T" / "async satisfies T" as a cast, not an arrow (oven-sh#34246)
  js_parser: accept `!`, `#name`, and `export @dec` in standard decorator grammar (oven-sh#34245)
  ...

# Conflicts:
#	test/js/bun/websocket/websocket-server.test.ts
robobun added a commit that referenced this pull request Jul 18, 2026
springmin pushed a commit to springmin/bun that referenced this pull request Aug 16, 2026
…exOf

Merge e66279d resolved conflicts by keeping the pre-fix uint32_t
versions, reintroducing upstream bugs oven-sh#34273/oven-sh#34274 (odd-length ucs2
indexOf with Buffer needles, 2^32-byte write/toString truncation).
JSBuffer.cpp has no OHOS-specific code, so restore the upstream file.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants