From ee334fb70f71d5d522f3d2d93d922bc44419cca9 Mon Sep 17 00:00:00 2001 From: Yusuke Suzuki Date: Mon, 10 Jul 2023 21:02:31 -0700 Subject: [PATCH] [JSC] Update ArrayBuffer#resize's detach check timing https://bugs.webkit.org/show_bug.cgi?id=259076 rdar://112041092 Reviewed by Mark Lam. Change the order of detach check according to the latest spec[1], but this only changes the type of error (from RangeError to TypeError). [1]: https://github.com/tc39/ecma262/pull/3116 * JSTests/stress/arraybuffer-resizable-resize-update.js: Added. (shouldThrow): * Source/JavaScriptCore/runtime/JSArrayBufferPrototype.cpp: (JSC::JSC_DEFINE_HOST_FUNCTION): Canonical link: https://commits.webkit.org/265935@main --- .../arraybuffer-resizable-resize-update.js | 24 +++++++++++++++++++ .../runtime/JSArrayBufferPrototype.cpp | 6 ++--- 2 files changed, 27 insertions(+), 3 deletions(-) create mode 100644 JSTests/stress/arraybuffer-resizable-resize-update.js diff --git a/JSTests/stress/arraybuffer-resizable-resize-update.js b/JSTests/stress/arraybuffer-resizable-resize-update.js new file mode 100644 index 0000000000000..0b761a5b1007e --- /dev/null +++ b/JSTests/stress/arraybuffer-resizable-resize-update.js @@ -0,0 +1,24 @@ +function shouldThrow(func, errorMessage) { + var errorThrown = false; + var error = null; + try { + func(); + } catch (e) { + errorThrown = true; + error = e; + } + if (!errorThrown) + throw new Error('not thrown'); + if (String(error) !== errorMessage) + throw new Error(`bad error: ${String(error)}`); +} + +let buffer = new ArrayBuffer(16, {maxByteLength: 16}); +shouldThrow(() => { + buffer.resize({ + valueOf() { + $.detachArrayBuffer(buffer); + return 0; + } + }); +}, `TypeError: Receiver is detached`); diff --git a/Source/JavaScriptCore/runtime/JSArrayBufferPrototype.cpp b/Source/JavaScriptCore/runtime/JSArrayBufferPrototype.cpp index 18c3294d535d2..558529fdd8989 100644 --- a/Source/JavaScriptCore/runtime/JSArrayBufferPrototype.cpp +++ b/Source/JavaScriptCore/runtime/JSArrayBufferPrototype.cpp @@ -278,12 +278,12 @@ JSC_DEFINE_HOST_FUNCTION(arrayBufferProtoFuncResize, (JSGlobalObject* globalObje if (UNLIKELY(!thisObject->impl()->isResizableOrGrowableShared())) return throwVMTypeError(globalObject, scope, "ArrayBuffer is not resizable"_s); - if (UNLIKELY(thisObject->impl()->isDetached())) - return throwVMTypeError(globalObject, scope, "Receiver is detached"_s); - double newLength = callFrame->argument(0).toIntegerOrInfinity(globalObject); RETURN_IF_EXCEPTION(scope, { }); + if (UNLIKELY(thisObject->impl()->isDetached())) + return throwVMTypeError(globalObject, scope, "Receiver is detached"_s); + if (!std::isfinite(newLength) || newLength < 0) return throwVMRangeError(globalObject, scope, "new length is out of range"_s); size_t newByteLength = static_cast(newLength);