fixed TypedArray constructor semantics which removes a buffer overflow (#478)

This commit is contained in:
Fabrice Bellard 2026-03-21 12:23:53 +01:00
parent 0989d4cb4a
commit 68caa5f226
3 changed files with 35 additions and 26 deletions

2
TODO

@ -63,4 +63,4 @@ Test262o: 0/11262 errors, 463 excluded
Test262o commit: 7da91bceb9ce7613f87db47ddd1292a2dda58b42 (es5-tests branch)
Test262:
Result: 64/83341 errors, 2567 excluded, 5767 skipped
Result: 62/83341 errors, 2567 excluded, 5767 skipped

@ -58148,38 +58148,54 @@ static JSValue js_typed_array_constructor(JSContext *ctx,
if (JS_VALUE_GET_TAG(argv[0]) != JS_TAG_OBJECT) {
if (JS_ToIndex(ctx, &len, argv[0]))
return JS_EXCEPTION;
obj = js_create_from_ctor(ctx, new_target, classid);
if (JS_IsException(obj))
return JS_EXCEPTION;
buffer = js_array_buffer_constructor1(ctx, JS_UNDEFINED,
len << size_log2,
NULL);
if (JS_IsException(buffer))
return JS_EXCEPTION;
goto fail;
offset = 0;
} else {
JSObject *p = JS_VALUE_GET_OBJ(argv[0]);
if (p->class_id == JS_CLASS_ARRAY_BUFFER ||
p->class_id == JS_CLASS_SHARED_ARRAY_BUFFER) {
abuf = p->u.array_buffer;
if (JS_ToIndex(ctx, &offset, argv[1]))
obj = js_create_from_ctor(ctx, new_target, classid);
if (JS_IsException(obj))
return JS_EXCEPTION;
if (abuf->detached)
return JS_ThrowTypeErrorDetachedArrayBuffer(ctx);
if ((offset & ((1 << size_log2) - 1)) != 0 ||
offset > abuf->byte_length)
return JS_ThrowRangeError(ctx, "invalid offset");
if (JS_ToIndex(ctx, &offset, argv[1]))
goto fail;
if ((offset & ((1 << size_log2) - 1)) != 0)
goto invalid_offset;
abuf = p->u.array_buffer;
if (JS_IsUndefined(argv[2])) {
if (abuf->detached) {
JS_ThrowTypeErrorDetachedArrayBuffer(ctx);
goto fail;
}
if (offset > abuf->byte_length) {
invalid_offset:
JS_ThrowRangeError(ctx, "invalid offset");
goto fail;
}
track_rab = array_buffer_is_resizable(abuf);
if (!track_rab)
if (!track_rab) {
if ((abuf->byte_length & ((1 << size_log2) - 1)) != 0)
goto invalid_length;
}
len = (abuf->byte_length - offset) >> size_log2;
} else {
if (JS_ToIndex(ctx, &len, argv[2]))
return JS_EXCEPTION;
if (abuf->detached)
return JS_ThrowTypeErrorDetachedArrayBuffer(ctx);
goto fail;
if (abuf->detached) {
JS_ThrowTypeErrorDetachedArrayBuffer(ctx);
goto fail;
}
if ((offset + (len << size_log2)) > abuf->byte_length) {
invalid_length:
return JS_ThrowRangeError(ctx, "invalid length");
JS_ThrowRangeError(ctx, "invalid length");
goto fail;
}
}
buffer = JS_DupValue(ctx, argv[0]);
@ -58193,17 +58209,12 @@ static JSValue js_typed_array_constructor(JSContext *ctx,
}
}
}
obj = js_create_from_ctor(ctx, new_target, classid);
if (JS_IsException(obj)) {
JS_FreeValue(ctx, buffer);
return JS_EXCEPTION;
}
if (typed_array_init(ctx, obj, buffer, offset, len, track_rab)) {
JS_FreeValue(ctx, obj);
return JS_EXCEPTION;
}
if (typed_array_init(ctx, obj, buffer, offset, len, track_rab))
goto fail;
return obj;
fail:
JS_FreeValue(ctx, obj);
return JS_EXCEPTION;
}
static void js_typed_array_finalizer(JSRuntime *rt, JSValue val)

@ -33,8 +33,6 @@ test262/test/staging/sm/Function/invalid-parameter-list.js:13: Test262Error: Exp
test262/test/staging/sm/Function/invalid-parameter-list.js:13: strict mode: Test262Error: Expected a SyntaxError to be thrown but no exception was thrown at all
test262/test/staging/sm/String/string-upper-lower-mapping.js:16: Test262Error: Expected SameValue(«"꟏"», «"꟎"») to be true
test262/test/staging/sm/String/string-upper-lower-mapping.js:16: strict mode: Test262Error: Expected SameValue(«"꟏"», «"꟎"») to be true
test262/test/staging/sm/TypedArray/constructor-buffer-sequence.js:29: Test262Error: Expected a ExpectedError but got a Error
test262/test/staging/sm/TypedArray/constructor-buffer-sequence.js:29: strict mode: Test262Error: Expected a ExpectedError but got a Error
test262/test/staging/sm/TypedArray/prototype-constructor-identity.js:17: Test262Error: Expected SameValue(«2», «6») to be true
test262/test/staging/sm/TypedArray/prototype-constructor-identity.js:17: strict mode: Test262Error: Expected SameValue(«2», «6») to be true
test262/test/staging/sm/async-functions/async-contains-unicode-escape.js:11: Test262Error: Expected a SyntaxError to be thrown but no exception was thrown at all