Bug 979481 - Separate the lifetime of the SafeJSContext global from that of the SafeJSContext itself. r=bz

This commit is contained in:
Bobby Holley 2014-03-06 08:55:00 -08:00
Родитель 7cf243add5
Коммит cacdca44ee
4 изменённых файлов: 38 добавлений и 11 удалений

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

@ -23,6 +23,11 @@ using mozilla::dom::DestroyProtoAndIfaceCache;
XPCJSContextStack::~XPCJSContextStack() XPCJSContextStack::~XPCJSContextStack()
{ {
if (mSafeJSContext) { if (mSafeJSContext) {
{
JSAutoRequest ar(mSafeJSContext);
JS_RemoveObjectRoot(mSafeJSContext, &mSafeJSContextGlobal);
}
mSafeJSContextGlobal = nullptr;
JS_DestroyContextNoGC(mSafeJSContext); JS_DestroyContextNoGC(mSafeJSContext);
mSafeJSContext = nullptr; mSafeJSContext = nullptr;
} }
@ -142,6 +147,13 @@ XPCJSContextStack::GetSafeJSContext()
return mSafeJSContext; return mSafeJSContext;
} }
JSObject*
XPCJSContextStack::GetSafeJSContextGlobal()
{
MOZ_ASSERT(mSafeJSContextGlobal);
return mSafeJSContextGlobal;
}
JSContext* JSContext*
XPCJSContextStack::InitSafeJSContext() XPCJSContextStack::InitSafeJSContext()
{ {
@ -164,31 +176,30 @@ XPCJSContextStack::InitSafeJSContext()
MOZ_CRASH(); MOZ_CRASH();
JSAutoRequest req(mSafeJSContext); JSAutoRequest req(mSafeJSContext);
JS::RootedObject glob(mSafeJSContext);
JS_SetErrorReporter(mSafeJSContext, xpc::SystemErrorReporter); JS_SetErrorReporter(mSafeJSContext, xpc::SystemErrorReporter);
JS::CompartmentOptions options; JS::CompartmentOptions options;
options.setZone(JS::SystemZone); options.setZone(JS::SystemZone);
glob = xpc::CreateGlobalObject(mSafeJSContext, &SafeJSContextGlobalClass, principal, options); mSafeJSContextGlobal = CreateGlobalObject(mSafeJSContext,
if (!glob) &SafeJSContextGlobalClass,
principal, options);
if (!mSafeJSContextGlobal)
MOZ_CRASH(); MOZ_CRASH();
JS_AddNamedObjectRoot(mSafeJSContext, &mSafeJSContextGlobal, "SafeJSContext global");
// Make sure the context is associated with a proper compartment // Make sure the context is associated with a proper compartment
// and not the default compartment. // and not the default compartment.
js::SetDefaultObjectForContext(mSafeJSContext, glob); js::SetDefaultObjectForContext(mSafeJSContext, mSafeJSContextGlobal);
// Note: make sure to set the private before calling // Note: make sure to set the private before calling
// InitClasses // InitClasses
nsRefPtr<SandboxPrivate> sp = new SandboxPrivate(principal, glob); nsRefPtr<SandboxPrivate> sp = new SandboxPrivate(principal, mSafeJSContextGlobal);
JS_SetPrivate(glob, sp.forget().get()); JS_SetPrivate(mSafeJSContextGlobal, sp.forget().get());
// After this point either glob is null and the if (NS_FAILED(xpc->InitClasses(mSafeJSContext, mSafeJSContextGlobal)))
// nsIScriptObjectPrincipal ownership is either handled by the
// nsCOMPtr or dealt with, or we'll release in the finalize
// hook.
if (NS_FAILED(xpc->InitClasses(mSafeJSContext, glob)))
MOZ_CRASH(); MOZ_CRASH();
JS::RootedObject glob(mSafeJSContext, mSafeJSContextGlobal);
JS_FireOnNewGlobalObject(mSafeJSContext, glob); JS_FireOnNewGlobalObject(mSafeJSContext, glob);
return mSafeJSContext; return mSafeJSContext;

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

@ -586,6 +586,12 @@ GetJunkScopeGlobal()
return GetNativeForGlobal(junkScope); return GetNativeForGlobal(junkScope);
} }
JSObject *
GetSafeJSContextGlobal()
{
return XPCJSRuntime::Get()->GetJSContextStack()->GetSafeJSContextGlobal();
}
nsGlobalWindow* nsGlobalWindow*
WindowGlobalOrNull(JSObject *aObj) WindowGlobalOrNull(JSObject *aObj)
{ {

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

@ -2777,6 +2777,7 @@ public:
XPCJSContextStack(XPCJSRuntime *aRuntime) XPCJSContextStack(XPCJSRuntime *aRuntime)
: mRuntime(aRuntime) : mRuntime(aRuntime)
, mSafeJSContext(nullptr) , mSafeJSContext(nullptr)
, mSafeJSContextGlobal(nullptr)
{ } { }
virtual ~XPCJSContextStack(); virtual ~XPCJSContextStack();
@ -2793,6 +2794,7 @@ public:
JSContext *InitSafeJSContext(); JSContext *InitSafeJSContext();
JSContext *GetSafeJSContext(); JSContext *GetSafeJSContext();
JSObject *GetSafeJSContextGlobal();
bool HasJSContext(JSContext *cx); bool HasJSContext(JSContext *cx);
const InfallibleTArray<XPCJSContextInfo>* GetStack() const InfallibleTArray<XPCJSContextInfo>* GetStack()
@ -2811,6 +2813,7 @@ private:
AutoInfallibleTArray<XPCJSContextInfo, 16> mStack; AutoInfallibleTArray<XPCJSContextInfo, 16> mStack;
XPCJSRuntime* mRuntime; XPCJSRuntime* mRuntime;
JSContext* mSafeJSContext; JSContext* mSafeJSContext;
JSObject* mSafeJSContextGlobal;
}; };
/***************************************************************************/ /***************************************************************************/

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

@ -424,6 +424,13 @@ GetJunkScope();
nsIGlobalObject * nsIGlobalObject *
GetJunkScopeGlobal(); GetJunkScopeGlobal();
/**
* Returns the dummy global associated with the SafeJSContext. Callers MUST
* consult with the XPConnect module owner before using this function.
*/
JSObject *
GetSafeJSContextGlobal();
/** /**
* If |aObj| has a window for a global, returns the associated nsGlobalWindow. * If |aObj| has a window for a global, returns the associated nsGlobalWindow.
* Otherwise, returns null. * Otherwise, returns null.