fix: guard u64 handle precision loss at Deno rawFetch and Tauri FFI boundary - #254
Merged
Conversation
…oundary Opaque bigint handles are slotmap u64 keys (32-bit slot + 32-bit generation). Two FFI paths converted them to JS number via raw Number(...) with no safe-range check, so a handle above 2^53 would silently round and address the wrong resource. - Deno: extract a shared bigintToSafeNumber() guard and use it in both the generic call() replacer and the rawFetch fast-path, so the fast path now throws RangeError like the slow path instead of truncating. - Tauri guest-js: add a u64Handle() boundary guard and apply it to every opaque bigint handle/token site (nextChunk, sendChunk, finishBody, cancelRequest, cancelFetch, rawFetch, respond_to_request). Endpoint handles are u32 numbers and left unchanged. - Add Deno regression tests asserting out-of-range handles are rejected rather than silently truncated. Closes #252
This was referenced Jun 26, 2026
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Summary
Opaque
biginthandles are slotmapu64keys (32-bit slot index + 32-bit generation). Two FFI paths converted them to JSnumbervia rawNumber(...)with no safe-range check, so a handle above2^53would silently round and address the wrong resource. The generic Denocall()path already guarded this exact case, making these two paths inconsistent outliers.Closes #252.
Changes
packages/iroh-http-deno/src/adapter.ts): extracted a sharedbigintToSafeNumber()guard and used it in both the genericcall()replacer and therawFetchfast-path, so the fast-path now throwsRangeErrorlike the slow path instead of silently truncating.packages/iroh-http-tauri/guest-js/index.ts): added au64Handle()boundary guard and applied it to every opaquebiginthandle/token site (nextChunk,sendChunk,finishBody,cancelRequest,cancelFetch,rawFetch,respond_to_request). Endpoint handles are u32numbers and were left unchanged.packages/iroh-http-deno/test/adapter.test.ts): added regression tests asserting out-of-range handles are rejected rather than silently truncated.deno.lock: resolved@std/assertentry pulled in by the new test'sassertThrows.Verification
npm run typecheckclean across all packages.deno fmtapplied.Notes / out of scope
rawServe()handler-drain gap (no tracking of pending handler promises, unlike Deno'sawait Promise.allSettled([...pending])) is intentionally not included — it needs the Rust-side serve drain semantics confirmed first and will be filed separately.iroh_http_start_fetch_cbcallback race was investigated and dismissed: the FFI symbol is blocking andfetchResolvers.setruns synchronously before theawait, so the cross-thread callback cannot be delivered first.u64in Rust" change, which would touch every plugin command signature.