Skip to content

fix(ext/webgpu): bounds-check + view-aware setBindGroup Uint32Array fast path - #33980

Merged
crowlKats merged 5 commits into
denoland:mainfrom
lunadogbot:lunadogbot/fix-webgpu-setbindgroup
Jun 9, 2026
Merged

crowlKats merged 5 commits into
denoland:mainfrom
lunadogbot:lunadogbot/fix-webgpu-setbindgroup

Conversation

@lunadogbot

@lunadogbot lunadogbot commented May 12, 2026 •

Copy link
Copy Markdown
Contributor

The Uint32Array fast path of setBindGroup in compute_pass.rs, render_pass.rs and render_bundle.rs had two related bugs (#33956):

  1. &data[start..(start + len)] sliced unchecked. An out-of-range length panicked inside the op's extern "C" callback, and the panic crossed the C ABI as a process abort β€” six lines of JS could kill a running runtime. This PR adds an explicit bounds check that surfaces as a GPUValidationError (or a thrown JS error in the render-bundle path, which has no per-call error_handler) instead.
  2. uint_32.buffer(scope).data() + ab.byte_length() / 4 walked the backing ArrayBuffer and ignored the typed-array view's byteOffset and length. A Uint32Array(buf, byteOffset > 0, …) fed wgpu_core the wrong window with no error surfaced β€” silently incorrect rendering / compute results. The slice is now constructed from byte_offset() + length().

Adds a regression test (gated on !isCIWithoutGPU, like the other webgpu tests) that:

  • calls setBindGroup(…, new Uint32Array(4), 0, 1_000_000) against both a ComputePass (expects a validation error in the device error scope) and a RenderBundleEncoder (expects a thrown JS error), and
  • confirms a well-formed call still works.

deno fmt --check and deno lint are clean on the changed files; the Rust changes will get their fmt/clippy from CI.

Out of scope: a view-window behavioural test (Uint32Array(buf, byteOffset=16, length=4) producing the right wgpu binding) needs a full pipeline + buffer + dispatch + readback to observe; the reporter's standalone Rust harness in #33956 demonstrates the semantics of the fix.

Credit to @hibrian827 for the diagnosis, three reproducers, and the suggested fix in the upstream report.

Fixes #33956.

@bartlomieju


πŸ€– Filed by agor (worker work2-2, bot lunadogbot). Tracking claim: bartlomieju/agent-job-board#24. (Note: @lunadogbot still needs CLA acceptance from the operator side, same as #33978.)

…ast path

The Uint32Array fast path of setBindGroup in compute_pass.rs,
render_pass.rs and render_bundle.rs had two related bugs (denoland#33956):

1. `&data[start..(start + len)]` sliced unchecked. An out-of-range
   length panicked inside the op's `extern "C"` callback and the
   panic crossed the C ABI as a process abort β€” six lines of JS
   could kill a running runtime. Add an explicit bounds check that
   surfaces as a GPUValidationError (or a thrown JS error in the
   render-bundle path, which has no per-call error_handler) instead.

2. `uint_32.buffer(scope).data()` + `ab.byte_length() / 4` walked
   the backing ArrayBuffer and ignored the typed-array view's
   `byteOffset` and `length`. A `Uint32Array(buf, byteOffset > 0,
   …)` fed wgpu_core the wrong window with no error surfaced β€”
   silently incorrect rendering / compute results. Construct the
   slice from `byte_offset()` + `length()` instead.

Adds a regression test (gated on `!isCIWithoutGPU`) that calls
setBindGroup with start=0 + len=1_000_000 on a 4-element
Uint32Array, against both a ComputePass (expects validation error
in the device error scope) and a RenderBundleEncoder (expects a
thrown JS error), and confirms a well-formed call still works.

Credit to @hibrian827 for the diagnosis, three repros, and the
suggested fix in the upstream report.

Fixes denoland#33956.

Signed-off-by: lunadogbot <lunadogbot@users.noreply.github.com>
`tools/lint.js` ran dprint+rustfmt and asked for the
`let Some(end) = ... else { ... }` condition on one line.

Signed-off-by: lunadogbot <lunadogbot@users.noreply.github.com>
@deno-cla-assistant

deno-cla-assistant Bot commented May 12, 2026 •

Copy link
Copy Markdown

Deno Individual Contributor License Agreement

All contributors have signed the CLA. Thank you!

Re-run CLA check


This is an automated message from CLA Assistant

@lunadogbot

Copy link
Copy Markdown
Contributor Author

CI is green (134 success, 2 skipped, 0 failures). Ready for review when you have a moment, @bartlomieju.

Same CLA blocker as #33978: @lunadogbot still needs CLA acceptance from the operator side before this can be merged.

@crowlKats
crowlKats merged commit 35d3602 into denoland:main Jun 9, 2026
268 of 270 checks 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.

ext/webgpu setBindGroup Uint32Array fast path: missing bounds check and reads from backing buffer instead of view byteOffset

3 participants