diff --git a/Makefile b/Makefile index 1f10b3b..4f63239 100644 --- a/Makefile +++ b/Makefile @@ -456,6 +456,7 @@ test: qjs$(EXE) $(WINE) ./qjs$(EXE) tests/test_worker.js $(WINE) ./qjs$(EXE) tests/bug1301.js $(WINE) ./qjs$(EXE) tests/bug1302.js + $(WINE) ./qjs$(EXE) tests/bug1305.js ifndef CONFIG_WIN32 $(WINE) ./qjs$(EXE) tests/test_std.js endif diff --git a/quickjs.c b/quickjs.c index 4a2beac..63b8696 100644 --- a/quickjs.c +++ b/quickjs.c @@ -58121,6 +58121,10 @@ static JSValue js_typed_array_constructor_ta(JSContext *ctx, JS_ThrowTypeErrorArrayBufferOOB(ctx); goto fail; } + if (len > p->u.array.count) { + JS_ThrowRangeError(ctx, "length out of bounds"); + goto fail; + } ta = p->u.typed_array; src_buffer = ta->buffer; src_abuf = src_buffer->u.array_buffer; diff --git a/tests/bug1305.js b/tests/bug1305.js new file mode 100644 index 0000000..1cfc5ec --- /dev/null +++ b/tests/bug1305.js @@ -0,0 +1,26 @@ +import {assert} from "./assert.js" + +const rab = new ArrayBuffer(10, { maxByteLength: 10 }); +const src = new Uint8Array(rab, 0); + +function f() { + return 1337; +} + +const EvilConstructor = new Proxy(function(){}, { + get: function(target, prop, receiver) { + if (prop === 'prototype') { + rab.resize(0); + return Uint8Array.prototype; + } + return Reflect.get(target, prop, receiver); + } +}); + +try { + let u8 = Reflect.construct(Uint8Array, [src], EvilConstructor); + print(u8); + throw Error("Should not get here"); +} catch (e) { + assert(e instanceof RangeError); +}