Skip to content

Commit 1ab4972

Browse files
committed
For TypedArrays read byteOffset before getting start and final
Previously, in issue #418 and pr #417 I misread the spec that in `subarray` we should be able to access the `byteOffset` from a detached buffer. Thinking more about it, something didn't seem right and I started a discussion in the TC39 group [1]. It turns out we shouldn't be able to read the ``byteOffset`` from detched buffers. Instead, the spec says we should just read the `byteOffset` value before we access `start` and `finish`. In the test262 test [2] the buffer is detached when accessing the `end` inside the `valueOf()` conversion, and the test expects to see the `byteOffset` before it was detached. So to fix it, ensure we access and save the `byteOffset` value first, then get the `start` and `finish`. [1] https://es.discourse.group/t/typedarray-subarray-byteoffset-with-detached-buffers/2381 [2] https://github.com/tc39/test262/blob/main/test/built-ins/TypedArray/prototype/subarray/byteoffset-with-detached-buffer.js
1 parent 458c34d commit 1ab4972

File tree

1 file changed

+14
-6
lines changed

1 file changed

+14
-6
lines changed

quickjs.c

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -54097,14 +54097,24 @@ static JSValue js_typed_array_subarray(JSContext *ctx, JSValueConst this_val,
5409754097
int argc, JSValueConst *argv)
5409854098
{
5409954099
JSValueConst args[4];
54100-
JSValue arr, ta_buffer;
54101-
JSTypedArray *ta;
54100+
JSValue arr, byteOffset, ta_buffer;
5410254101
JSObject *p;
54103-
int len, start, final, count, shift, offset;
54102+
int len, start, final, count, shift, byte_offset, offset;
5410454103

5410554104
p = get_typed_array(ctx, this_val, 0);
5410654105
if (!p)
5410754106
goto exception;
54107+
54108+
/* Fetch byteOffset first, then access start and final. It's technically
54109+
possible for the buffer to be detached when accessing start of final, by
54110+
way of `valueOf()` for instance, and the spec indicates we should preserve
54111+
the byteOffset value from before it might be detached */
54112+
byteOffset = js_typed_array_get_byteOffset(ctx, this_val, 0);
54113+
if (JS_IsException(byteOffset))
54114+
goto exception;
54115+
byte_offset = JS_VALUE_GET_INT(byteOffset);
54116+
JS_FreeValue(ctx, byteOffset);
54117+
5410854118
len = p->u.array.count;
5410954119
if (JS_ToInt32Clamp(ctx, &start, argv[0], 0, len, len))
5411054120
goto exception;
@@ -54116,9 +54126,7 @@ static JSValue js_typed_array_subarray(JSContext *ctx, JSValueConst this_val,
5411654126
}
5411754127
count = max_int(final - start, 0);
5411854128
shift = typed_array_size_log2(p->class_id);
54119-
ta = p->u.typed_array;
54120-
/* Read byteOffset (ta->offset) even if detached */
54121-
offset = ta->offset + (start << shift);
54129+
offset = byte_offset + (start << shift);
5412254130
ta_buffer = js_typed_array_get_buffer(ctx, this_val, 0);
5412354131
if (JS_IsException(ta_buffer))
5412454132
goto exception;

0 commit comments

Comments
 (0)