Bug 1673793 - detachArrayBuffer and ArrayBuffer-stealing capabilities should permit wrapped ArrayBuffers. r=anba

Differential Revision: https://phabricator.services.mozilla.com/D95101
This commit is contained in:
Jeff Walden 2020-10-29 07:58:50 +00:00
Родитель 85f53704b2
Коммит 57b620bc42
3 изменённых файлов: 32 добавлений и 44 удалений

Просмотреть файл

@ -636,6 +636,7 @@ MSG_DEF(JSMSG_TYPED_ARRAY_CALL_OR_CONSTRUCT, 1, JSEXN_TYPEERR, "cannot directly
MSG_DEF(JSMSG_NON_TYPED_ARRAY_RETURNED, 0, JSEXN_TYPEERR, "constructor didn't return TypedArray object")
MSG_DEF(JSMSG_SHORT_TYPED_ARRAY_RETURNED, 2, JSEXN_TYPEERR, "expected TypedArray of at least length {0}, but constructor returned TypedArray of length {1}")
MSG_DEF(JSMSG_TYPED_ARRAY_NOT_COMPATIBLE, 2, JSEXN_TYPEERR, "{0} elements are incompatible with {1}")
MSG_DEF(JSMSG_ARRAYBUFFER_REQUIRED, 0, JSEXN_TYPEERR, "ArrayBuffer object required")
// Shared array buffer
MSG_DEF(JSMSG_SHARED_ARRAY_BAD_LENGTH, 0, JSEXN_RANGEERR, "length argument out of range")

Просмотреть файл

@ -311,11 +311,6 @@ skip script test262/built-ins/TypedArrayConstructors/internals/DefineOwnProperty
skip script test262/built-ins/TypedArrayConstructors/internals/DefineOwnProperty/key-is-numericindex-desc-configurable.js
skip script test262/built-ins/TypedArrayConstructors/internals/DefineOwnProperty/BigInt/key-is-numericindex-desc-configurable.js
# https://bugzilla.mozilla.org/show_bug.cgi?id=1673793
# All of these tests pass except with --more-compartments.
ignore-flag(--more-compartments) script test262/built-ins/TypedArrayConstructors/internals/Delete/detached-buffer-realm.js
ignore-flag(--more-compartments) script test262/built-ins/TypedArrayConstructors/internals/Delete/BigInt/detached-buffer-realm.js
# https://bugzilla.mozilla.org/show_bug.cgi?id=1297179
# All of these tests pass except with --more-compartments.
ignore-flag(--more-compartments) script test262/built-ins/Proxy/apply/arguments-realm.js

Просмотреть файл

@ -61,6 +61,7 @@
#include "gc/Nursery-inl.h"
#include "vm/JSAtom-inl.h"
#include "vm/NativeObject-inl.h"
#include "vm/Realm-inl.h" // js::AutoRealm
#include "vm/Shape-inl.h"
using JS::ToInt32;
@ -1687,25 +1688,41 @@ JS_FRIEND_API uint8_t* JS::GetArrayBufferData(JSObject* obj,
return aobj->dataPointer();
}
static ArrayBufferObject* UnwrapArrayBuffer(
JSContext* cx, JS::Handle<JSObject*> maybeArrayBuffer) {
JSObject* obj = CheckedUnwrapStatic(maybeArrayBuffer);
if (!obj) {
ReportAccessDenied(cx);
return nullptr;
}
if (!obj->is<ArrayBufferObject>()) {
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
JSMSG_ARRAYBUFFER_REQUIRED);
return nullptr;
}
return &obj->as<ArrayBufferObject>();
}
JS_FRIEND_API bool JS::DetachArrayBuffer(JSContext* cx, HandleObject obj) {
AssertHeapIsIdle();
CHECK_THREAD(cx);
cx->check(obj);
if (!obj->is<ArrayBufferObject>()) {
JS_ReportErrorASCII(cx, "ArrayBuffer object required");
Rooted<ArrayBufferObject*> unwrappedBuffer(cx, UnwrapArrayBuffer(cx, obj));
if (!unwrappedBuffer) {
return false;
}
Rooted<ArrayBufferObject*> buffer(cx, &obj->as<ArrayBufferObject>());
if (buffer->isWasm() || buffer->isPreparedForAsmJS()) {
if (unwrappedBuffer->isWasm() || unwrappedBuffer->isPreparedForAsmJS()) {
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
JSMSG_WASM_NO_TRANSFER);
return false;
}
ArrayBufferObject::detach(cx, buffer);
AutoRealm ar(cx, unwrappedBuffer);
ArrayBufferObject::detach(cx, unwrappedBuffer);
return true;
}
@ -1743,23 +1760,6 @@ JS_PUBLIC_API JSObject* JS::NewArrayBufferWithContents(JSContext* cx,
return ArrayBufferObject::createForContents(cx, nbytes, contents);
}
static ArrayBufferObject* UnwrapArrayBuffer(
JSContext* cx, JS::Handle<JSObject*> maybeArrayBuffer) {
JSObject* obj = CheckedUnwrapStatic(maybeArrayBuffer);
if (!obj) {
ReportAccessDenied(cx);
return nullptr;
}
if (!obj->is<ArrayBufferObject>()) {
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
JSMSG_TYPED_ARRAY_BAD_ARGS);
return nullptr;
}
return &obj->as<ArrayBufferObject>();
}
JS_PUBLIC_API JSObject* JS::CopyArrayBuffer(JSContext* cx,
Handle<JSObject*> arrayBuffer) {
AssertHeapIsIdle();
@ -1823,38 +1823,30 @@ JS_FRIEND_API JSObject* JS::UnwrapSharedArrayBuffer(JSObject* obj) {
}
JS_PUBLIC_API void* JS::StealArrayBufferContents(JSContext* cx,
HandleObject objArg) {
HandleObject obj) {
AssertHeapIsIdle();
CHECK_THREAD(cx);
cx->check(objArg);
cx->check(obj);
JSObject* obj = CheckedUnwrapStatic(objArg);
if (!obj) {
ReportAccessDenied(cx);
Rooted<ArrayBufferObject*> unwrappedBuffer(cx, UnwrapArrayBuffer(cx, obj));
if (!unwrappedBuffer) {
return nullptr;
}
if (!obj->is<ArrayBufferObject>()) {
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
JSMSG_TYPED_ARRAY_BAD_ARGS);
return nullptr;
}
Rooted<ArrayBufferObject*> buffer(cx, &obj->as<ArrayBufferObject>());
if (buffer->isDetached()) {
if (unwrappedBuffer->isDetached()) {
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
JSMSG_TYPED_ARRAY_DETACHED);
return nullptr;
}
if (buffer->isWasm() || buffer->isPreparedForAsmJS()) {
if (unwrappedBuffer->isWasm() || unwrappedBuffer->isPreparedForAsmJS()) {
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
JSMSG_WASM_NO_TRANSFER);
return nullptr;
}
AutoRealm ar(cx, buffer);
return ArrayBufferObject::stealMallocedContents(cx, buffer);
AutoRealm ar(cx, unwrappedBuffer);
return ArrayBufferObject::stealMallocedContents(cx, unwrappedBuffer);
}
JS_PUBLIC_API JSObject* JS::NewMappedArrayBufferWithContents(JSContext* cx,