You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Object.freeze throws for a typed array whose buffer is detached #1765
v is returned. The buffer is not resizable, and a detached view has no elements to freeze.
V8 (15.6.20):
$ v8 -e 'const b = new ArrayBuffer(8); const v = new Float32Array(b); b.transfer(); print(Object.freeze(v) === v);'true
Actual (QuickJS-ng)
QuickJS-ng reports the view as resizable:
$ qjs -e 'const b = new ArrayBuffer(8); const v = new Float32Array(b); b.transfer(); print(Object.freeze(v) === v);'
TypeError: cannot freeze resizable typed array
Spec
Object.freeze calls SetIntegrityLevel with frozen. Its first step is O.[[PreventExtensions]](); for a TypedArray, [[PreventExtensions]] returns false only when IsTypedArrayFixedLength is false. A fixed-length view on a non-resizable buffer is fixed-length whether or not the buffer is detached, so this succeeds.
SetIntegrityLevel then makes every own key non-configurable and non-writable. A detached view has no integer-indexed keys, so nothing can fail and Object.freeze returns v.
QuickJS-ng agrees with this everywhere except Object.freeze: Object.preventExtensions(v) succeeds on the same view, after which Object.isFrozen(v) is true. The freeze path additionally rejects any view that is out of bounds, and a detached view counts as out of bounds even though its buffer is not resizable.
For context: #1691 (fixed by PR #1695) added the resizable-buffer check to Object.preventExtensions, where Object.freeze already had it; this report is about the extra out-of-bounds condition that only Object.freeze applies.
JavaScriptCore, SpiderMonkey, GraalJS, XS and V8 all return the typed array.
In js_object_seal, the freeze path threw when the backing buffer was resizable or when typed_array_is_oob was true. Detachment makes the view out of bounds even if the buffer was never resizable, so that second check rejected a view that is still fixed-length.
The freeze guard now throws only when array_buffer_is_resizable is true, and a detached fixed-length view continues through the normal freeze path and is returned.
Activity
mvanhorn commentedon Oct 12, 2026
In js_object_seal, the freeze path threw when the backing buffer was resizable or when typed_array_is_oob was true. Detachment makes the view out of bounds even if the buffer was never resizable, so that second check rejected a view that is still fixed-length.
The freeze guard now throws only when array_buffer_is_resizable is true, and a detached fixed-length view continues through the normal freeze path and is returned.
#1824