]> git.kaiwu.me - quickjs.git/commitdiff
Read byteOffset for detached buffers
authorNick Vatamaniuc <vatamane@gmail.com>
Sat, 7 Jun 2025 04:42:50 +0000 (00:42 -0400)
committerNick Vatamaniuc <vatamane@gmail.com>
Sat, 7 Jun 2025 05:37:54 +0000 (01:37 -0400)
The spec [1] expects to read `byteOffset` even for detached buffers.

Noticed a new test262 test [2] failed and there an an existing one we skipped
as well for the same reason.

[1] https://tc39.es/ecma262/#sec-%typedarray%.prototype.subarray
[2] https://github.com/tc39/test262/blob/main/test/built-ins/TypedArray/prototype/subarray/byteoffset-with-detached-buffer.js

Fix: https://github.com/bellard/quickjs/issues/417

quickjs.c
test262_errors.txt

index 34346f49e84d9759d4ed60c37d84daa8c29c474a..f271927c287e31c4a83f9c40e5b2e9b501b16e81 100644 (file)
--- a/quickjs.c
+++ b/quickjs.c
@@ -54017,7 +54017,8 @@ static JSValue js_typed_array_subarray(JSContext *ctx, JSValueConst this_val,
                                        int argc, JSValueConst *argv)
 {
     JSValueConst args[4];
-    JSValue arr, byteOffset, ta_buffer;
+    JSValue arr, ta_buffer;
+    JSTypedArray *ta;
     JSObject *p;
     int len, start, final, count, shift, offset;
 
@@ -54034,12 +54035,10 @@ static JSValue js_typed_array_subarray(JSContext *ctx, JSValueConst this_val,
             goto exception;
     }
     count = max_int(final - start, 0);
-    byteOffset = js_typed_array_get_byteOffset(ctx, this_val, 0);
-    if (JS_IsException(byteOffset))
-        goto exception;
     shift = typed_array_size_log2(p->class_id);
-    offset = JS_VALUE_GET_INT(byteOffset) + (start << shift);
-    JS_FreeValue(ctx, byteOffset);
+    ta = p->u.typed_array;
+    /* Read byteOffset (ta->offset) even if detached */
+    offset = ta->offset + (start << shift);
     ta_buffer = js_typed_array_get_buffer(ctx, this_val, 0);
     if (JS_IsException(ta_buffer))
         goto exception;
index 9df6f749a2f38f0b64b0101a7330994036d734d1..7dd3f7624bdb2a9efbe0275a273289280ad6b342 100644 (file)
@@ -23,7 +23,6 @@ test262/test/staging/sm/TypedArray/prototype-constructor-identity.js:17: Test262
 test262/test/staging/sm/TypedArray/set-detached-bigint.js:27: Error: Assertion failed: expected exception SyntaxError, got RangeError: invalid array length
 test262/test/staging/sm/TypedArray/set-detached.js:112: RangeError: invalid array length
 test262/test/staging/sm/TypedArray/sort_modifications.js:12: Test262Error: Int8Array at index 0 for size 4 Expected SameValue(«0», «1») to be true
-test262/test/staging/sm/TypedArray/subarray.js:15: Test262Error: Expected SameValue(«0», «1») to be true
 test262/test/staging/sm/async-functions/async-contains-unicode-escape.js:45: Error: Assertion failed: expected exception SyntaxError, no exception thrown
 test262/test/staging/sm/async-functions/await-error.js:12: Test262Error: Expected SameValue(«false», «true») to be true
 test262/test/staging/sm/async-functions/await-in-arrow-parameters.js:33: Error: Assertion failed: expected exception SyntaxError, no exception thrown - AsyncFunction:(a = (b = await/r/g) => {}) => {}