Skip to content

Don't throw oob exception when setting numeric indexes on TAs #647

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Nov 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 3 additions & 23 deletions quickjs.c
Original file line number Diff line number Diff line change
Expand Up @@ -1215,7 +1215,6 @@ static JSValue js_typed_array_constructor_ta(JSContext *ctx,
JSValue src_obj,
int classid, uint32_t len);
static BOOL typed_array_is_oob(JSObject *p);
static BOOL typed_array_is_resizable(JSObject *p);
static uint32_t typed_array_get_length(JSContext *ctx, JSObject *p);
static JSValue JS_ThrowTypeErrorDetachedArrayBuffer(JSContext *ctx);
static JSValue JS_ThrowTypeErrorArrayBufferOOB(JSContext *ctx);
Expand Down Expand Up @@ -9034,14 +9033,9 @@ static int JS_SetPropertyValue(JSContext *ctx, JSValue this_obj,
if (unlikely(idx >= (uint32_t)p->u.array.count)) {
ta_out_of_bound:
if (typed_array_is_oob(p))
if (!(flags & JS_PROP_DEFINE_PROPERTY))
return TRUE; // per spec: no OOB exception
// XXX(bnoordhuis) questionable but generic methods like
// Array.prototype.fill invoked on RABs can end up here
// and should, per spec, not error
if (typed_array_is_resizable(p))
return TRUE;
return JS_ThrowTypeErrorOrFalse(ctx, flags, "out-of-bound numeric index");
if (flags & JS_PROP_DEFINE_PROPERTY)
return JS_ThrowTypeErrorOrFalse(ctx, flags, "out-of-bound numeric index");
return TRUE; // per spec: no OOB exception
}
p->u.array.u.double_ptr[idx] = d;
break;
Expand Down Expand Up @@ -51745,20 +51739,6 @@ static BOOL typed_array_is_oob(JSObject *p)
return end > len;
}

// |p| must be a typed array, *not* a DataView
static BOOL typed_array_is_resizable(JSObject *p)
{
JSArrayBuffer *abuf;
JSTypedArray *ta;

assert(p->class_id >= JS_CLASS_UINT8C_ARRAY);
assert(p->class_id <= JS_CLASS_FLOAT64_ARRAY);

ta = p->u.typed_array;
abuf = ta->buffer->u.array_buffer;
return array_buffer_is_resizable(abuf);
}

/* WARNING: 'p' must be a typed array. Works even if the array buffer
is detached */
static uint32_t typed_array_get_length(JSContext *ctx, JSObject *p)
Expand Down
4 changes: 4 additions & 0 deletions tests/bug645/0.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
"use strict";

const u8 = new Uint8Array(1);
u8[100] = 123; // Should not throw.
9 changes: 9 additions & 0 deletions tests/bug645/1.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { assert, assertThrows } from "../assert.js";
const ab = new ArrayBuffer(1);
const u8 = new Uint8Array(ab);
assert(!ab.detached);
// Detach the ArrayBuffer.
ab.transfer();
assert(ab.detached);
u8[100] = 123; // Doesn't throw.
assertThrows(TypeError, () => Object.defineProperty(u8, "100", { value: 123 }));
7 changes: 7 additions & 0 deletions tests/bug645/2.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { assert, assertThrows } from "../assert.js";
const ab = new ArrayBuffer(16, { maxByteLength: 32 });
const u8 = new Uint8Array(ab, 16);
ab.resize(8);
assert(ab.byteLength, 8);
u8[1] = 123; // Doesn't throw.
assertThrows(TypeError, () => Object.defineProperty(u8, "1", { value: 123 }));
Loading