Skip to content

Commit e30da0e

Browse files
committed
Don't throw oob exception when setting numeric indexes on TAs
Relevant spec section: https://tc39.es/ecma262/multipage/ordinary-and-exotic-objects-behaviours.html#sec-typedarraysetelement It should only throw if Object.defineProperty is used and the TA is detached or OOB if a RAB is used. Fixes: #645
1 parent 9c5c441 commit e30da0e

File tree

4 files changed

+23
-23
lines changed

4 files changed

+23
-23
lines changed

quickjs.c

Lines changed: 3 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1215,7 +1215,6 @@ static JSValue js_typed_array_constructor_ta(JSContext *ctx,
12151215
JSValue src_obj,
12161216
int classid, uint32_t len);
12171217
static BOOL typed_array_is_oob(JSObject *p);
1218-
static BOOL typed_array_is_resizable(JSObject *p);
12191218
static uint32_t typed_array_get_length(JSContext *ctx, JSObject *p);
12201219
static JSValue JS_ThrowTypeErrorDetachedArrayBuffer(JSContext *ctx);
12211220
static JSValue JS_ThrowTypeErrorArrayBufferOOB(JSContext *ctx);
@@ -9034,14 +9033,9 @@ static int JS_SetPropertyValue(JSContext *ctx, JSValue this_obj,
90349033
if (unlikely(idx >= (uint32_t)p->u.array.count)) {
90359034
ta_out_of_bound:
90369035
if (typed_array_is_oob(p))
9037-
if (!(flags & JS_PROP_DEFINE_PROPERTY))
9038-
return TRUE; // per spec: no OOB exception
9039-
// XXX(bnoordhuis) questionable but generic methods like
9040-
// Array.prototype.fill invoked on RABs can end up here
9041-
// and should, per spec, not error
9042-
if (typed_array_is_resizable(p))
9043-
return TRUE;
9044-
return JS_ThrowTypeErrorOrFalse(ctx, flags, "out-of-bound numeric index");
9036+
if (flags & JS_PROP_DEFINE_PROPERTY)
9037+
return JS_ThrowTypeErrorOrFalse(ctx, flags, "out-of-bound numeric index");
9038+
return TRUE; // per spec: no OOB exception
90459039
}
90469040
p->u.array.u.double_ptr[idx] = d;
90479041
break;
@@ -51745,20 +51739,6 @@ static BOOL typed_array_is_oob(JSObject *p)
5174551739
return end > len;
5174651740
}
5174751741

51748-
// |p| must be a typed array, *not* a DataView
51749-
static BOOL typed_array_is_resizable(JSObject *p)
51750-
{
51751-
JSArrayBuffer *abuf;
51752-
JSTypedArray *ta;
51753-
51754-
assert(p->class_id >= JS_CLASS_UINT8C_ARRAY);
51755-
assert(p->class_id <= JS_CLASS_FLOAT64_ARRAY);
51756-
51757-
ta = p->u.typed_array;
51758-
abuf = ta->buffer->u.array_buffer;
51759-
return array_buffer_is_resizable(abuf);
51760-
}
51761-
5176251742
/* WARNING: 'p' must be a typed array. Works even if the array buffer
5176351743
is detached */
5176451744
static uint32_t typed_array_get_length(JSContext *ctx, JSObject *p)

tests/bug645/0.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
"use strict";
2+
3+
const u8 = new Uint8Array(1);
4+
u8[100] = 123; // Should not throw.

tests/bug645/1.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import { assert, assertThrows } from "../assert.js";
2+
const ab = new ArrayBuffer(1);
3+
const u8 = new Uint8Array(ab);
4+
assert(!ab.detached);
5+
// Detach the ArrayBuffer.
6+
ab.transfer();
7+
assert(ab.detached);
8+
u8[100] = 123; // Doesn't throw.
9+
assertThrows(TypeError, () => Object.defineProperty(u8, "100", { value: 123 }));

tests/bug645/2.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import { assert, assertThrows } from "../assert.js";
2+
const ab = new ArrayBuffer(16, { maxByteLength: 32 });
3+
const u8 = new Uint8Array(ab, 16);
4+
ab.resize(8);
5+
assert(ab.byteLength, 8);
6+
u8[1] = 123; // Doesn't throw.
7+
assertThrows(TypeError, () => Object.defineProperty(u8, "1", { value: 123 }));

0 commit comments

Comments
 (0)