Skip to content

fix(ext/node): select the detached-buffer contract of isAscii and isUtf8 - #32

Merged
jackspirou merged 1 commit into
nimbus/v2.9.7from
fix/buffer-detached-validation
Sep 24, 2026
Merged

jackspirou merged 1 commit into
nimbus/v2.9.7from
fix/buffer-detached-validation

Conversation

@jackspirou

Copy link
Copy Markdown
Contributor

Summary

Node.js changed how buffer.isAscii() and buffer.isUtf8() treat a detached ArrayBuffer (nodejs/node#64504):

  • Node.js 24.20, 26.7, and earlier throw ERR_INVALID_STATE: "Cannot validate on a detached buffer".
  • Node.js 24.21, 26.8, and later treat the input as empty and return true. This applies to a detached ArrayBuffer and to a Buffer or TypedArray view backed by one.

The fork always threw. The Nimbus node24 (v24.21.0) and node26 (v26.10.0) lanes fail test-buffer-isascii.js and test-buffer-isutf8.js for this reason.

Change

  • Add deno_node::BufferDetachedValidationPolicy with Throw and TreatAsEmpty. The embedder passes it in the deno_node options, the same as the other versioned Node policies.
  • op_node_buffer_detached_validation_throws reads the policy. With no policy in the state, it keeps Throw, which is the upstream behavior.
  • isAscii() and isUtf8() share one detached check. For TreatAsEmpty, they return true before they build a Uint8Array, because that constructor throws for a detached ArrayBuffer.
  • The Deno runtime passes Throw. Deno's node_compat suite tracks Node.js 26.5.1, which throws.
  • The Nimbus fork CI now runs buffer_test.

Upstream Deno main still throws. This is a temporary carry. Removal trigger: upstream Deno adopts the nodejs/node#64504 contract for the Node.js versions that it targets.

Verification (macOS arm64)

  • unit_node buffer_test: ok. The new test covers isAscii and isUtf8 with a detached ArrayBuffer, Buffer, Uint8Array, and Float64Array.
  • node_compat test-buffer-is*: 4 passed (test-buffer-isascii.js, test-buffer-isutf8.js, test-buffer-isutf8-isascii-fast.js, test-buffer-isencoding.js).
  • cargo test -p deno_node --lib --features deno_core/default policy: 5 passed, including the new policy test.
  • The CI clippy command for the carry crates: clean. cargo fmt --check and dprint with .dprint.json: clean.

The Nimbus consumer maps node20 and node22 to Throw, and node24, node26, and the non-Node targets to TreatAsEmpty. That change lands with the next Nimbus repin.

Node.js 24.21 and 26.8 (nodejs/node#64504) treat a detached ArrayBuffer,
or a view backed by one, as empty input: buffer.isAscii() and
buffer.isUtf8() return true. Earlier releases throw ERR_INVALID_STATE.

Add BufferDetachedValidationPolicy so that an embedder selects the
contract of its Node.js target. Deno keeps Throw, because its node_compat
suite tracks Node.js 26.5.1. The TreatAsEmpty path returns before it
builds a Uint8Array, because the constructor throws for a detached
ArrayBuffer.

Run buffer_test in the Nimbus fork CI.
@jackspirou
jackspirou merged commit 23fdb71 into nimbus/v2.9.7 Sep 24, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant