Skip to content

Fix CompactSize.toBytes silently truncating values above 2^64 - 1 - #503

Merged
jxom merged 1 commit into
wevm:mainfrom
ara-stock:fix/compactsize-uint64-overflow
Nov 8, 2026
Merged

jxom merged 1 commit into
wevm:mainfrom
ara-stock:fix/compactsize-uint64-overflow

Conversation

@ara-stock

Copy link
Copy Markdown
Contributor

CompactSize.toBytes (and toHex, which goes through it) checks the lower bound (NegativeValueError) but not the upper bound. For values above 2^64 - 1, the 9-byte branch calls DataView#setBigUint64, which reduces its argument modulo 2^64 and does not throw. You get the encoding of a different number back, with no error:

import { CompactSize } from 'ox'

CompactSize.toHex(2n ** 64n + 2n ** 32n)
// 0xff0000000001000000
CompactSize.fromHex('0xff0000000001000000').value
// 4294967296n  (= 2^32, not the input)

CompactSize.toHex(2n ** 64n)
// 0xff0000000000000000, which CompactSize.fromHex rejects with NonMinimalEncodingError

This PR adds an upper-bound check that throws a new CompactSize.ValueTooLargeError, which has the same shape as NegativeValueError. 2^64 - 1 still encodes as before.

Before / after (toHex → fromHex):

input before after
2^64 - 1 0xffffffffffffffffff → 2^64 - 1 unchanged
2^64 0xff0000000000000000 → NonMinimalEncodingError throws ValueTooLargeError
2^64 + 2^32 0xff0000000001000000 → 4294967296n throws ValueTooLargeError

Alternatives considered: reusing InvalidValueError. I didn't, because its message and parameter are specific to non-safe-integer numbers.

The same code is on 0.x, if a backport is wanted.

Tests: added toBytes > error: value larger than uint64. It fails on main ("snapshot function didn't throw") and passes with the fix. pnpm test --project core src/core/_test/CompactSize.test.ts (16 passed), vp check on the touched files, and pnpm check:types all pass. A patch changeset is included.

I used an AI assistant (Claude) while preparing this. I reproduced the issue and checked the fix and tests myself.

`DataView#setBigUint64` reduces its argument modulo 2^64, so
`CompactSize.toBytes` silently wrapped values above 2^64 - 1 into a
different 9-byte encoding (e.g. 2^64 + 2^32 encoded as 2^32). Throw
`CompactSize.ValueTooLargeError` instead, mirroring the existing
`NegativeValueError` lower-bound check.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@vercel

vercel Bot commented Oct 7, 2026

Copy link
Copy Markdown

@ara-stock is attempting to deploy a commit to the Wevm Team on Vercel.

A member of the Team first needs to authorize it.

@jxom
jxom merged commit 97a4cce into wevm:main Nov 8, 2026
2 of 3 checks passed
@github-actions github-actions Bot mentioned this pull request Nov 8, 2026
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.

2 participants