ReviewOS

zig-utils/zig-js

TypedArray: preserve rounded decimal property names

#1058
Closed chris opened this 8 days ago ·
8 days ago

Parent: #498 Discovered by: #1057

TypedArray generic Get/Set admits digit-only keys through arrayIndex without checking whether Number-to-string round-tripping preserves the key.

Executed reproduction:

let values = new Uint8Array(1), coerced = 0;
let payload = { valueOf() { coerced++; return 7; } };
values["9007199254740993"] = payload;
[coerced, typeof values["9007199254740993"], Object.hasOwn(values, "9007199254740993")].join(",");

Node: 0,object,true. Saved before binary in both tree and required-bytecode modes: 1,undefined,false.

The string is not a CanonicalNumericIndexString: its Number conversion rounds to 9007199254740992. Ordinary [[Set]] must retain the payload as a named property without ToNumber; ordinary [[Get]] must return it.

Acceptance:

  • Both generic TypedArray Get and Set use the shared CanonicalNumericIndexString classifier.
  • Keep direct parsing for exactly representable ordinary index strings in that shared classifier.
  • Pin rounded digit-only keys, descriptor reads, delete/redefinition, inherited named properties, and canonical invalid indices against Node.
  • Normal/unsuppressed TSan tests and before/after TypedArray internals corpus checks pass.
8 days ago

Fixed in 9eb494e.

Generic TypedArray Get/Set now use the shared CanonicalNumericIndexString classifier. Rounded decimal names such as 9007199254740993 stay ordinary properties, while exact canonical invalid indices retain Integer-Indexed semantics. Direct parsing for exact ordinary decimal indices is owned by the shared classifier.

The executed Node probe changed from 1,undefined,false to 0,object,true in both tree and required-bytecode modes. The pinned matrix also covers descriptor reads, deletion/redefinition, inherited named properties, canonical invalid indices, and ordinary named properties on BigInt views.

Validation: focused normal and unsuppressed TSan tests each pass 2/2. The entire pinned TypedArray internals corpus is byte-identical before/after: 240 pass, zero failures, zero flips. Its tree-vs-required-bytecode witness reports 240 agreements and zero divergences on both sides.

Sign in to comment on this issue.