mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-08 02:14:43 +00:00
Bug 1891118 - Move arraybuffer diagnostic assertions into spidermonkey r=peterv,jandem
Differential Revision: https://phabricator.services.mozilla.com/D207310
This commit is contained in:
parent
48ec93874d
commit
d8e98a7383
@ -13,6 +13,7 @@
|
||||
|
||||
#include "js/ArrayBuffer.h"
|
||||
#include "js/ArrayBufferMaybeShared.h"
|
||||
#include "js/Context.h"
|
||||
#include "js/experimental/TypedData.h" // js::Unwrap(Ui|I)nt(8|16|32)Array, js::Get(Ui|I)nt(8|16|32)ArrayLengthAndData, js::UnwrapUint8ClampedArray, js::GetUint8ClampedArrayLengthAndData, js::UnwrapFloat(32|64)Array, js::GetFloat(32|64)ArrayLengthAndData, JS_GetArrayBufferViewType
|
||||
#include "js/GCAPI.h" // JS::AutoCheckCannotGC
|
||||
#include "js/RootingAPI.h" // JS::Rooted
|
||||
@ -671,80 +672,9 @@ struct TypedArray_base : public SpiderMonkeyInterfaceObjectStorage,
|
||||
MOZ_CRASH("Null js::CheckedUnwrapStatic(mImplObj)");
|
||||
}
|
||||
}
|
||||
if (!JS::IsArrayBufferViewShared(view)) {
|
||||
JSAutoRealm ar(jsapi.cx(), view);
|
||||
bool unused;
|
||||
bool noBuffer;
|
||||
{
|
||||
JSObject* buffer =
|
||||
JS_GetArrayBufferViewBuffer(jsapi.cx(), view, &unused);
|
||||
noBuffer = !buffer;
|
||||
}
|
||||
if (noBuffer) {
|
||||
if (JS_IsTypedArrayObject(view)) {
|
||||
JS::Value bufferSlot =
|
||||
JS::GetReservedSlot(view, /* BUFFER_SLOT */ 0);
|
||||
if (bufferSlot.isNull()) {
|
||||
MOZ_CRASH("TypedArrayObject with bufferSlot containing null");
|
||||
} else if (bufferSlot.isBoolean()) {
|
||||
// If we're here then TypedArrayObject::ensureHasBuffer must have
|
||||
// failed in the call to JS_GetArrayBufferViewBuffer.
|
||||
if (JS_IsThrowingOutOfMemory(jsapi.cx())) {
|
||||
size_t length = JS_GetTypedArrayByteLength(view);
|
||||
if (!JS::GetReservedSlot(view, /* DATA_SLOT */ 3)
|
||||
.isUndefined() &&
|
||||
length <= JS_MaxMovableTypedArraySize()) {
|
||||
MOZ_CRASH(
|
||||
"We did run out of memory, maybe trying to uninline the "
|
||||
"buffer");
|
||||
}
|
||||
if (length < INT32_MAX) {
|
||||
MOZ_CRASH(
|
||||
"We did run out of memory trying to create a buffer "
|
||||
"smaller than 2GB - 1");
|
||||
} else if (length < UINT32_MAX) {
|
||||
MOZ_CRASH(
|
||||
"We did run out of memory trying to create a between 2GB "
|
||||
"and 4GB - 1");
|
||||
} else {
|
||||
MOZ_CRASH(
|
||||
"We did run out of memory trying to create a buffer "
|
||||
"bigger than 4GB - 1");
|
||||
}
|
||||
} else if (JS_IsExceptionPending(jsapi.cx())) {
|
||||
JS::Rooted<JS::Value> exn(jsapi.cx());
|
||||
if (JS_GetPendingException(jsapi.cx(), &exn) &&
|
||||
exn.isObject()) {
|
||||
JS::Rooted<JSObject*> exnObj(jsapi.cx(), &exn.toObject());
|
||||
JSErrorReport* err =
|
||||
JS_ErrorFromException(jsapi.cx(), exnObj);
|
||||
if (err && err->errorNumber == JSMSG_BAD_ARRAY_LENGTH) {
|
||||
MOZ_CRASH("Length was too big");
|
||||
}
|
||||
}
|
||||
}
|
||||
// Did ArrayBufferObject::createBufferAndData fail without OOM?
|
||||
MOZ_CRASH("TypedArrayObject with bufferSlot containing boolean");
|
||||
} else if (bufferSlot.isObject()) {
|
||||
if (!bufferSlot.toObjectOrNull()) {
|
||||
MOZ_CRASH(
|
||||
"TypedArrayObject with bufferSlot containing null object");
|
||||
} else {
|
||||
MOZ_CRASH(
|
||||
"JS_GetArrayBufferViewBuffer failed but bufferSlot "
|
||||
"contains a non-null object");
|
||||
}
|
||||
} else {
|
||||
MOZ_CRASH(
|
||||
"TypedArrayObject with bufferSlot containing weird value");
|
||||
}
|
||||
} else {
|
||||
MOZ_CRASH("JS_GetArrayBufferViewBuffer failed for DataViewObject");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
JS::AutoBrittleMode abm(jsapi.cx());
|
||||
if (!JS::EnsureNonInlineArrayBufferOrView(jsapi.cx(), mImplObj)) {
|
||||
MOZ_CRASH("small oom when moving inline data out-of-line");
|
||||
}
|
||||
|
@ -843,6 +843,8 @@ static ArrayBufferContents AllocateUninitializedArrayBufferContents(
|
||||
p = static_cast<uint8_t*>(cx->runtime()->onOutOfMemoryCanGC(
|
||||
js::AllocFunction::Malloc, js::ArrayBufferContentsArena, nbytes));
|
||||
if (!p) {
|
||||
MOZ_DIAGNOSTIC_ASSERT(!cx->brittleMode,
|
||||
"OOM in AllocateUninitializedArrayBufferContents");
|
||||
ReportOutOfMemory(cx);
|
||||
}
|
||||
}
|
||||
@ -1753,6 +1755,7 @@ static ArrayBufferType* NewArrayBufferObject(JSContext* cx, HandleObject proto_,
|
||||
if (!proto) {
|
||||
proto = GlobalObject::getOrCreatePrototype(cx, JSProto_ArrayBuffer);
|
||||
if (!proto) {
|
||||
MOZ_DIAGNOSTIC_ASSERT(!cx->brittleMode, "creating ArrayBuffer proto");
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
@ -1770,6 +1773,7 @@ static ArrayBufferType* NewArrayBufferObject(JSContext* cx, HandleObject proto_,
|
||||
SharedShape::getInitialShape(cx, clasp, cx->realm(), AsTaggedProto(proto),
|
||||
nfixed, ObjectFlags()));
|
||||
if (!shape) {
|
||||
MOZ_DIAGNOSTIC_ASSERT(!cx->brittleMode, "get ArrayBuffer initial shape");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@ -1778,7 +1782,12 @@ static ArrayBufferType* NewArrayBufferObject(JSContext* cx, HandleObject proto_,
|
||||
MOZ_ASSERT(!CanNurseryAllocateFinalizedClass(clasp));
|
||||
constexpr gc::Heap heap = gc::Heap::Tenured;
|
||||
|
||||
return NativeObject::create<ArrayBufferType>(cx, allocKind, heap, shape);
|
||||
auto* buffer =
|
||||
NativeObject::create<ArrayBufferType>(cx, allocKind, heap, shape);
|
||||
if (!buffer) {
|
||||
MOZ_DIAGNOSTIC_ASSERT(!cx->brittleMode, "create NativeObject failed");
|
||||
}
|
||||
return buffer;
|
||||
}
|
||||
|
||||
// Creates a new ArrayBufferObject with %ArrayBuffer.prototype% as proto and no
|
||||
@ -1889,6 +1898,15 @@ ArrayBufferObject::createUninitializedBufferAndData(
|
||||
? AllocateUninitializedArrayBufferContents(cx, nbytes)
|
||||
: AllocateArrayBufferContents(cx, nbytes);
|
||||
if (!data) {
|
||||
if (cx->brittleMode) {
|
||||
if (nbytes < INT32_MAX) {
|
||||
MOZ_DIAGNOSTIC_ASSERT(false, "ArrayBuffer allocation OOM < 2GB - 1");
|
||||
} else {
|
||||
MOZ_DIAGNOSTIC_ASSERT(
|
||||
false,
|
||||
"ArrayBuffer allocation OOM between 2GB and ByteLengthLimit");
|
||||
}
|
||||
}
|
||||
return {nullptr, nullptr};
|
||||
}
|
||||
}
|
||||
@ -2247,6 +2265,7 @@ ArrayBufferObject* ArrayBufferObject::createZeroed(
|
||||
JSContext* cx, size_t nbytes, HandleObject proto /* = nullptr */) {
|
||||
// 24.1.1.1, step 3 (Inlined 6.2.6.1 CreateByteDataBlock, step 2).
|
||||
if (!CheckArrayBufferTooLarge(cx, nbytes)) {
|
||||
MOZ_DIAGNOSTIC_ASSERT(!cx->brittleMode, "buffer too large");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@ -2469,6 +2488,7 @@ bool ArrayBufferObject::ensureNonInline(JSContext* cx,
|
||||
if (buffer->isLengthPinned()) {
|
||||
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
|
||||
JSMSG_ARRAYBUFFER_LENGTH_PINNED);
|
||||
MOZ_DIAGNOSTIC_ASSERT(!cx->brittleMode, "ArrayBuffer length pinned");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -113,7 +113,11 @@ ArrayBufferObjectMaybeShared* ArrayBufferViewObject::ensureBufferObject(
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
return thisObject->bufferEither();
|
||||
auto* buffer = thisObject->bufferEither();
|
||||
if (!buffer) {
|
||||
MOZ_DIAGNOSTIC_ASSERT(!cx->brittleMode, "ABV has no buffer");
|
||||
}
|
||||
return buffer;
|
||||
}
|
||||
|
||||
bool ArrayBufferViewObject::init(JSContext* cx,
|
||||
@ -451,6 +455,7 @@ JS_PUBLIC_API JSObject* JS_GetArrayBufferViewBuffer(JSContext* cx,
|
||||
Rooted<ArrayBufferViewObject*> unwrappedView(
|
||||
cx, obj->maybeUnwrapAs<ArrayBufferViewObject>());
|
||||
if (!unwrappedView) {
|
||||
MOZ_DIAGNOSTIC_ASSERT(!cx->brittleMode, "access to buffer denied");
|
||||
ReportAccessDenied(cx);
|
||||
return nullptr;
|
||||
}
|
||||
@ -468,6 +473,7 @@ JS_PUBLIC_API JSObject* JS_GetArrayBufferViewBuffer(JSContext* cx,
|
||||
|
||||
RootedObject buffer(cx, unwrappedBuffer);
|
||||
if (!cx->compartment()->wrap(cx, &buffer)) {
|
||||
MOZ_DIAGNOSTIC_ASSERT(!cx->brittleMode, "wrapping buffer failed");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@ -586,6 +592,8 @@ JS_PUBLIC_API bool JS::PinArrayBufferOrViewLength(JSObject* obj, bool pin) {
|
||||
return view->pinLength(pin);
|
||||
}
|
||||
|
||||
MOZ_DIAGNOSTIC_ASSERT(!js::TlsContext.get()->brittleMode,
|
||||
"invalid type in PinABOVLength");
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -612,6 +620,7 @@ JS_PUBLIC_API bool JS::EnsureNonInlineArrayBufferOrView(JSContext* cx,
|
||||
return ArrayBufferViewObject::ensureNonInline(cx, rootedView);
|
||||
}
|
||||
|
||||
MOZ_DIAGNOSTIC_ASSERT(!cx->brittleMode, "unhandled type");
|
||||
JS_ReportErrorASCII(cx, "unhandled type");
|
||||
return false;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user