From 8baafc46bda3f09c508eb656f295dbe0565ca958 Mon Sep 17 00:00:00 2001 From: Ben Noordhuis Date: Tue, 12 Dec 2023 23:14:33 +0100 Subject: [PATCH] Don't throw OOB exception for detached typed array (#208) `a[42] = 1` where a is a detached typed array should not throw but `Object.defineProperty()` still should. Add a check and a flag that distinguishes between the two cases. --- quickjs.c | 9 ++++++++- quickjs.h | 1 + test262_errors.txt | 5 +---- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/quickjs.c b/quickjs.c index 935c32c..28bede1 100644 --- a/quickjs.c +++ b/quickjs.c @@ -8429,6 +8429,9 @@ retry: JS_FreeValue(ctx, val); if (JS_IsException(val)) return -1; + if (typed_array_is_detached(ctx, p1)) + if (!(flags & JS_PROP_DEFINE_PROPERTY)) + return FALSE; // per spec: no OOB exception return JS_ThrowTypeErrorOrFalse(ctx, flags, "out-of-bound numeric index"); } } @@ -8687,6 +8690,9 @@ static int JS_SetPropertyValue(JSContext *ctx, JSValue this_obj, return -1; if (unlikely(idx >= (uint32_t)p->u.array.count)) { ta_out_of_bound: + if (typed_array_is_detached(ctx, p)) + if (!(flags & JS_PROP_DEFINE_PROPERTY)) + return FALSE; // per spec: no OOB exception return JS_ThrowTypeErrorOrFalse(ctx, flags, "out-of-bound numeric index"); } p->u.array.u.double_ptr[idx] = d; @@ -34488,7 +34494,8 @@ static __exception int JS_DefinePropertyDesc(JSContext *ctx, JSValue obj, return -1; ret = JS_DefineProperty(ctx, obj, prop, - d.value, d.getter, d.setter, d.flags | flags); + d.value, d.getter, d.setter, + d.flags | flags | JS_PROP_DEFINE_PROPERTY); js_free_desc(ctx, &d); return ret; } diff --git a/quickjs.h b/quickjs.h index 47e2153..eee0d02 100644 --- a/quickjs.h +++ b/quickjs.h @@ -246,6 +246,7 @@ static inline JS_BOOL JS_VALUE_IS_NAN(JSValue v) #define JS_PROP_NO_ADD (1 << 16) /* internal use */ #define JS_PROP_NO_EXOTIC (1 << 17) /* internal use */ +#define JS_PROP_DEFINE_PROPERTY (1 << 18) /* internal use */ #define JS_DEFAULT_STACK_SIZE (256 * 1024) diff --git a/test262_errors.txt b/test262_errors.txt index c6d68d0..821b47c 100644 --- a/test262_errors.txt +++ b/test262_errors.txt @@ -13,9 +13,8 @@ test262/test/built-ins/TypedArrayConstructors/internals/DefineOwnProperty/detach test262/test/built-ins/TypedArrayConstructors/internals/DefineOwnProperty/detached-buffer.js:47: strict mode: Test262Error: (Testing with Float64Array.) test262/test/built-ins/TypedArrayConstructors/internals/DefineOwnProperty/tonumber-value-detached-buffer.js:42: Test262Error: Reflect.defineProperty(ta, 0, {value: {valueOf() {$DETACHBUFFER(ta.buffer); return 42;}}} ) must return true Expected SameValue(«false», «true») to be true (Testing with Float64Array.) test262/test/built-ins/TypedArrayConstructors/internals/DefineOwnProperty/tonumber-value-detached-buffer.js:42: strict mode: Test262Error: Reflect.defineProperty(ta, 0, {value: {valueOf() {$DETACHBUFFER(ta.buffer); return 42;}}} ) must return true Expected SameValue(«false», «true») to be true (Testing with Float64Array.) -test262/test/built-ins/TypedArrayConstructors/internals/Set/BigInt/detached-buffer-realm.js:37: strict mode: TypeError: out-of-bound numeric index (Testing with BigInt64Array.) test262/test/built-ins/TypedArrayConstructors/internals/Set/BigInt/detached-buffer.js:34: TypeError: cannot convert bigint to number (Testing with BigInt64Array.) -test262/test/built-ins/TypedArrayConstructors/internals/Set/BigInt/detached-buffer.js:32: strict mode: TypeError: out-of-bound numeric index (Testing with BigInt64Array.) +test262/test/built-ins/TypedArrayConstructors/internals/Set/BigInt/detached-buffer.js:34: strict mode: TypeError: cannot convert bigint to number (Testing with BigInt64Array.) test262/test/built-ins/TypedArrayConstructors/internals/Set/BigInt/key-is-minus-zero.js:20: Test262Error: Reflect.set("new TA([42n])", "-0", 1n) must return true Expected SameValue(«false», «true») to be true (Testing with BigInt64Array.) test262/test/built-ins/TypedArrayConstructors/internals/Set/BigInt/key-is-minus-zero.js:20: strict mode: Test262Error: Reflect.set("new TA([42n])", "-0", 1n) must return true Expected SameValue(«false», «true») to be true (Testing with BigInt64Array.) test262/test/built-ins/TypedArrayConstructors/internals/Set/BigInt/key-is-not-integer.js:21: Test262Error: Reflect.set("new TA([42n])", "1.1", 1n) must return true Expected SameValue(«false», «true») to be true (Testing with BigInt64Array.) @@ -24,8 +23,6 @@ test262/test/built-ins/TypedArrayConstructors/internals/Set/BigInt/key-is-out-of test262/test/built-ins/TypedArrayConstructors/internals/Set/BigInt/key-is-out-of-bounds.js:27: strict mode: Test262Error: Reflect.set("new TA([42n])", "-1", 1n) must return false Expected SameValue(«false», «true») to be true (Testing with BigInt64Array.) test262/test/built-ins/TypedArrayConstructors/internals/Set/BigInt/tonumber-value-detached-buffer.js:24: Test262Error: Expected SameValue(«false», «true») to be true (Testing with BigInt64Array.) test262/test/built-ins/TypedArrayConstructors/internals/Set/BigInt/tonumber-value-detached-buffer.js:24: strict mode: Test262Error: Expected SameValue(«false», «true») to be true (Testing with BigInt64Array.) -test262/test/built-ins/TypedArrayConstructors/internals/Set/detached-buffer-realm.js:37: strict mode: TypeError: out-of-bound numeric index (Testing with Float64Array.) -test262/test/built-ins/TypedArrayConstructors/internals/Set/detached-buffer.js:32: strict mode: TypeError: out-of-bound numeric index (Testing with Float64Array.) test262/test/built-ins/TypedArrayConstructors/internals/Set/key-is-minus-zero.js:22: Test262Error: Reflect.set(sample, "-0", 1) must return true Expected SameValue(«false», «true») to be true (Testing with Float64Array.) test262/test/built-ins/TypedArrayConstructors/internals/Set/key-is-minus-zero.js:22: strict mode: Test262Error: Reflect.set(sample, "-0", 1) must return true Expected SameValue(«false», «true») to be true (Testing with Float64Array.) test262/test/built-ins/TypedArrayConstructors/internals/Set/key-is-not-integer.js:22: Test262Error: Reflect.set(sample, "1.1", 1) must return true Expected SameValue(«false», «true») to be true (Testing with Float64Array.)