mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-27 12:15:33 +00:00
Bug 1495573 - avoid double refcount decrement along failure path. r=luke
--HG-- extra : rebase_source : 0894f81f9828fd41a35dbd8c9ccbdfbea4ba58b2 extra : histedit_source : 383355a2244dfba407b54c0e2e1627f9b2a44784
This commit is contained in:
parent
d3446d7ede
commit
f3b4178593
@ -6686,34 +6686,44 @@ GetSharedObject(JSContext* cx, unsigned argc, Value* vp)
|
|||||||
// Flag was set in the sender; ensure it is set in the receiver.
|
// Flag was set in the sender; ensure it is set in the receiver.
|
||||||
MOZ_ASSERT(cx->realm()->creationOptions().getSharedMemoryAndAtomicsEnabled());
|
MOZ_ASSERT(cx->realm()->creationOptions().getSharedMemoryAndAtomicsEnabled());
|
||||||
|
|
||||||
|
// The protocol for creating a SAB requires the refcount to be
|
||||||
|
// incremented prior to the SAB creation.
|
||||||
|
|
||||||
SharedArrayRawBuffer* buf = mbx->val.sarb.buffer;
|
SharedArrayRawBuffer* buf = mbx->val.sarb.buffer;
|
||||||
uint32_t length = mbx->val.sarb.length;
|
uint32_t length = mbx->val.sarb.length;
|
||||||
if (!buf->addReference()) {
|
if (!buf->addReference()) {
|
||||||
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_SC_SAB_REFCNT_OFLO);
|
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_SC_SAB_REFCNT_OFLO);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
auto dropBuf = MakeScopeExit([buf] { buf->dropReference(); });
|
|
||||||
|
// If the allocation fails we must decrement the refcount before
|
||||||
|
// returning.
|
||||||
|
|
||||||
Rooted<ArrayBufferObjectMaybeShared*> maybesab(cx, SharedArrayBufferObject::New(cx, buf, length));
|
Rooted<ArrayBufferObjectMaybeShared*> maybesab(cx, SharedArrayBufferObject::New(cx, buf, length));
|
||||||
if (!maybesab) {
|
if (!maybesab) {
|
||||||
|
buf->dropReference();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// At this point the SAB was created successfully and it owns the
|
||||||
|
// refcount-increase on the buffer that we performed above. So even
|
||||||
|
// if we fail to allocate along any path below we must not decrement
|
||||||
|
// the refcount; the garbage collector must be allowed to handle
|
||||||
|
// that via finalization of the orphaned SAB object.
|
||||||
|
|
||||||
if (mbx->tag == MailboxTag::SharedArrayBuffer) {
|
if (mbx->tag == MailboxTag::SharedArrayBuffer) {
|
||||||
newObj = maybesab;
|
newObj = maybesab;
|
||||||
} else {
|
} else {
|
||||||
if (!GlobalObject::ensureConstructor(cx, cx->global(), JSProto_WebAssembly)) {
|
if (!GlobalObject::ensureConstructor(cx, cx->global(), JSProto_WebAssembly)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
RootedObject proto(cx, &cx->global()->getPrototype(JSProto_WasmMemory).toObject());
|
RootedObject proto(cx, &cx->global()->getPrototype(JSProto_WasmMemory).toObject());
|
||||||
newObj = WasmMemoryObject::create(cx, maybesab, proto);
|
newObj = WasmMemoryObject::create(cx, maybesab, proto);
|
||||||
MOZ_ASSERT_IF(newObj, newObj->as<WasmMemoryObject>().isShared());
|
MOZ_ASSERT_IF(newObj, newObj->as<WasmMemoryObject>().isShared());
|
||||||
|
if (!newObj) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (!newObj) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
dropBuf.release();
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user