mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 996785 - Fix CPOW wrapping and compartment ownership (r=mrbkap)
This commit is contained in:
parent
f080a0f66d
commit
366c658c5d
@ -7,6 +7,7 @@
|
||||
|
||||
#include "JavaScriptShared.h"
|
||||
#include "mozilla/dom/BindingUtils.h"
|
||||
#include "mozilla/dom/TabChild.h"
|
||||
#include "jsfriendapi.h"
|
||||
#include "xpcprivate.h"
|
||||
|
||||
@ -356,10 +357,41 @@ JavaScriptShared::ConvertID(const JSIID &from, nsID *to)
|
||||
to->m3[7] = from.m3_7();
|
||||
}
|
||||
|
||||
void
|
||||
JavaScriptShared::ReportNonexistentObject(JSContext *cx)
|
||||
JSObject *
|
||||
JavaScriptShared::findObjectById(JSContext *cx, uint32_t objId)
|
||||
{
|
||||
JS_ReportError(cx, "operation not possible on dead CPOW");
|
||||
RootedObject obj(cx, findObjectById(objId));
|
||||
if (!obj) {
|
||||
JS_ReportError(cx, "operation not possible on dead CPOW");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Objects are stored in objects_ unwrapped. We want to wrap the object
|
||||
// before returning it so that all operations happen on Xray wrappers. If
|
||||
// the object is a DOM element, we try to obtain the corresponding
|
||||
// TabChildGlobal and wrap in that.
|
||||
RootedObject global(cx, GetGlobalForObjectCrossCompartment(obj));
|
||||
nsCOMPtr<nsIGlobalObject> nativeGlobal = xpc::GetNativeForGlobal(global);
|
||||
nsCOMPtr<nsIDOMWindow> window = do_QueryInterface(nativeGlobal);
|
||||
if (window) {
|
||||
dom::TabChild *tabChild = dom::TabChild::GetFrom(window);
|
||||
if (tabChild) {
|
||||
nsCOMPtr<nsIContentFrameMessageManager> mm;
|
||||
tabChild->GetMessageManager(getter_AddRefs(mm));
|
||||
nsCOMPtr<nsIGlobalObject> tabChildNativeGlobal = do_QueryInterface(mm);
|
||||
RootedObject tabChildGlobal(cx, tabChildNativeGlobal->GetGlobalJSObject());
|
||||
JSAutoCompartment ac(cx, tabChildGlobal);
|
||||
if (!JS_WrapObject(cx, &obj))
|
||||
return nullptr;
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
|
||||
// If there's no TabChildGlobal, we use the junk scope.
|
||||
JSAutoCompartment ac(cx, xpc::GetJunkScope());
|
||||
if (!JS_WrapObject(cx, &obj))
|
||||
return nullptr;
|
||||
return obj;
|
||||
}
|
||||
|
||||
static const uint64_t DefaultPropertyOp = 1;
|
||||
|
@ -116,20 +116,13 @@ class JavaScriptShared
|
||||
static void ConvertID(const nsID &from, JSIID *to);
|
||||
static void ConvertID(const JSIID &from, nsID *to);
|
||||
|
||||
void ReportNonexistentObject(JSContext *cx);
|
||||
|
||||
JSObject *findCPOWById(uint32_t objId) {
|
||||
return cpows_.find(objId);
|
||||
}
|
||||
JSObject *findObjectById(uint32_t objId) {
|
||||
return objects_.find(objId);
|
||||
}
|
||||
JSObject *findObjectById(JSContext *cx, uint32_t objId) {
|
||||
if (JSObject *result = objects_.find(objId))
|
||||
return result;
|
||||
ReportNonexistentObject(cx);
|
||||
return nullptr;
|
||||
}
|
||||
JSObject *findObjectById(JSContext *cx, uint32_t objId);
|
||||
|
||||
protected:
|
||||
JSRuntime *rt_;
|
||||
|
@ -631,12 +631,18 @@ WrapperOwner::ok(JSContext *cx, const ReturnStatus &status)
|
||||
}
|
||||
|
||||
bool
|
||||
WrapperOwner::toObjectVariant(JSContext *cx, JSObject *obj, ObjectVariant *objVarp)
|
||||
WrapperOwner::toObjectVariant(JSContext *cx, JSObject *objArg, ObjectVariant *objVarp)
|
||||
{
|
||||
RootedObject obj(cx, objArg);
|
||||
JS_ASSERT(obj);
|
||||
JSObject *unwrapped = js::CheckedUnwrap(obj, false);
|
||||
if (unwrapped && IsCPOW(unwrapped) && OwnerOf(unwrapped) == this) {
|
||||
*objVarp = LocalObject(idOf(unwrapped));
|
||||
|
||||
// We always save objects unwrapped in the CPOW table. If we stored
|
||||
// wrappers, then the wrapper might be GCed while the target remained alive.
|
||||
// Whenever operating on an object that comes from the table, we wrap it
|
||||
// in findObjectById.
|
||||
obj = js::CheckedUnwrap(obj, false);
|
||||
if (obj && IsCPOW(obj) && OwnerOf(obj) == this) {
|
||||
*objVarp = LocalObject(idOf(obj));
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -646,6 +652,11 @@ WrapperOwner::toObjectVariant(JSContext *cx, JSObject *obj, ObjectVariant *objVa
|
||||
return true;
|
||||
}
|
||||
|
||||
// Need to call PreserveWrapper on |obj| in case it's a reflector.
|
||||
// FIXME: What if it's an XPCWrappedNative?
|
||||
if (mozilla::dom::IsDOMObject(obj))
|
||||
mozilla::dom::TryPreserveWrapper(obj);
|
||||
|
||||
id = ++lastId_;
|
||||
if (id > MAX_CPOW_IDS) {
|
||||
JS_ReportError(cx, "CPOW id limit reached");
|
||||
|
Loading…
Reference in New Issue
Block a user