mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 990729 - Add compartmentPerAddon option for XUL overlays (r=bholley)
This commit is contained in:
parent
1ddea0f108
commit
78c2618e3d
@ -82,6 +82,7 @@
|
||||
#include "nsXULPopupManager.h"
|
||||
#include "nsCCUncollectableMarker.h"
|
||||
#include "nsURILoader.h"
|
||||
#include "mozilla/AddonPathService.h"
|
||||
#include "mozilla/BasicEvents.h"
|
||||
#include "mozilla/dom/Element.h"
|
||||
#include "mozilla/dom/NodeInfoInlines.h"
|
||||
@ -3691,9 +3692,14 @@ XULDocument::ExecuteScript(nsIScriptContext * aContext,
|
||||
nsAutoMicroTask mt;
|
||||
JSContext *cx = aContext->GetNativeContext();
|
||||
AutoCxPusher pusher(cx);
|
||||
JS::Rooted<JSObject*> global(cx, mScriptGlobalObject->GetGlobalJSObject());
|
||||
JS::Rooted<JSObject*> baseGlobal(cx, mScriptGlobalObject->GetGlobalJSObject());
|
||||
NS_ENSURE_TRUE(baseGlobal, NS_ERROR_FAILURE);
|
||||
NS_ENSURE_TRUE(nsContentUtils::GetSecurityManager()->ScriptAllowed(baseGlobal), NS_OK);
|
||||
|
||||
JSAddonId *addonId = MapURIToAddonID(mCurrentPrototype->GetURI());
|
||||
JS::Rooted<JSObject*> global(cx, xpc::GetAddonScope(cx, baseGlobal, addonId));
|
||||
NS_ENSURE_TRUE(global, NS_ERROR_FAILURE);
|
||||
NS_ENSURE_TRUE(nsContentUtils::GetSecurityManager()->ScriptAllowed(global), NS_OK);
|
||||
|
||||
JS::ExposeObjectToActiveJS(global);
|
||||
xpc_UnmarkGrayScript(aScriptObject);
|
||||
JSAutoCompartment ac(cx, global);
|
||||
|
@ -6,6 +6,7 @@
|
||||
// Microsoft's API Name hackery sucks
|
||||
#undef CreateEvent
|
||||
|
||||
#include "mozilla/AddonPathService.h"
|
||||
#include "mozilla/BasicEvents.h"
|
||||
#include "mozilla/CycleCollectedJSRuntime.h"
|
||||
#include "mozilla/EventDispatcher.h"
|
||||
@ -842,6 +843,8 @@ EventListenerManager::CompileEventHandlerInternal(Listener* aListener,
|
||||
typeAtom, win,
|
||||
&argCount, &argNames);
|
||||
|
||||
JSAddonId *addonId = MapURIToAddonID(uri);
|
||||
|
||||
// Wrap the event target, so that we can use it as the scope for the event
|
||||
// handler. Note that mTarget is different from aElement in the <body> case,
|
||||
// where mTarget is a Window.
|
||||
@ -858,6 +861,17 @@ EventListenerManager::CompileEventHandlerInternal(Listener* aListener,
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
if (addonId) {
|
||||
JS::Rooted<JSObject*> vObj(cx, &v.toObject());
|
||||
JS::Rooted<JSObject*> addonScope(cx, xpc::GetAddonScope(cx, vObj, addonId));
|
||||
if (!addonScope) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
JSAutoCompartment ac(cx, addonScope);
|
||||
if (!JS_WrapValue(cx, &v)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
}
|
||||
JS::Rooted<JSObject*> target(cx, &v.toObject());
|
||||
JSAutoCompartment ac(cx, target);
|
||||
|
||||
|
@ -44,6 +44,7 @@
|
||||
#include "nsCxPusher.h"
|
||||
#include "WrapperFactory.h"
|
||||
|
||||
#include "mozilla/AddonPathService.h"
|
||||
#include "mozilla/scache/StartupCache.h"
|
||||
#include "mozilla/scache/StartupCacheUtils.h"
|
||||
#include "mozilla/MacroForEach.h"
|
||||
@ -682,7 +683,9 @@ mozJSComponentLoader::PrepareObjectForLocation(JSCLContextHelper& aCx,
|
||||
|
||||
CompartmentOptions options;
|
||||
options.setZone(SystemZone)
|
||||
.setVersion(JSVERSION_LATEST);
|
||||
.setVersion(JSVERSION_LATEST)
|
||||
.setAddonId(aReuseLoaderGlobal ? nullptr : MapURIToAddonID(aURI));
|
||||
|
||||
// Defer firing OnNewGlobalObject until after the __URI__ property has
|
||||
// been defined so the JS debugger can tell what module the global is
|
||||
// for
|
||||
|
@ -522,6 +522,14 @@ IsInContentXBLScope(JSObject *obj)
|
||||
return IsContentXBLScope(js::GetObjectCompartment(obj));
|
||||
}
|
||||
|
||||
bool
|
||||
IsInAddonScope(JSObject *obj)
|
||||
{
|
||||
// We always eagerly create compartment privates for addon scopes.
|
||||
XPCWrappedNativeScope *scope = GetObjectScope(obj);
|
||||
return scope && scope->IsAddonScope();
|
||||
}
|
||||
|
||||
bool
|
||||
IsUniversalXPConnectEnabled(JSCompartment *compartment)
|
||||
{
|
||||
|
@ -73,7 +73,8 @@ XPCWrappedNativeScope::XPCWrappedNativeScope(JSContext *cx,
|
||||
mComponents(nullptr),
|
||||
mNext(nullptr),
|
||||
mGlobalJSObject(aGlobal),
|
||||
mIsContentXBLScope(false)
|
||||
mIsContentXBLScope(false),
|
||||
mIsAddonScope(false)
|
||||
{
|
||||
// add ourselves to the scopes list
|
||||
{
|
||||
@ -185,6 +186,20 @@ XPCWrappedNativeScope::AttachComponentsObject(JSContext* aCx)
|
||||
JSPROP_PERMANENT | JSPROP_READONLY);
|
||||
}
|
||||
|
||||
static bool
|
||||
CompartmentPerAddon()
|
||||
{
|
||||
static bool initialized = false;
|
||||
static bool pref = false;
|
||||
|
||||
if (!initialized) {
|
||||
pref = Preferences::GetBool("dom.compartment_per_addon", false);
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
return pref;
|
||||
}
|
||||
|
||||
JSObject*
|
||||
XPCWrappedNativeScope::EnsureContentXBLScope(JSContext *cx)
|
||||
{
|
||||
@ -249,6 +264,8 @@ XPCWrappedNativeScope::AllowContentXBLScope()
|
||||
namespace xpc {
|
||||
JSObject *GetXBLScope(JSContext *cx, JSObject *contentScopeArg)
|
||||
{
|
||||
MOZ_ASSERT(!IsInAddonScope(contentScopeArg));
|
||||
|
||||
JS::RootedObject contentScope(cx, contentScopeArg);
|
||||
JSAutoCompartment ac(cx, contentScope);
|
||||
JSObject *scope = EnsureCompartmentPrivate(contentScope)->scope->EnsureContentXBLScope(cx);
|
||||
@ -274,6 +291,57 @@ UseContentXBLScope(JSCompartment *c)
|
||||
|
||||
} /* namespace xpc */
|
||||
|
||||
JSObject*
|
||||
XPCWrappedNativeScope::EnsureAddonScope(JSContext *cx, JSAddonId *addonId)
|
||||
{
|
||||
JS::RootedObject global(cx, GetGlobalJSObject());
|
||||
MOZ_ASSERT(js::IsObjectInContextCompartment(global, cx));
|
||||
MOZ_ASSERT(!mIsContentXBLScope);
|
||||
MOZ_ASSERT(!mIsAddonScope);
|
||||
MOZ_ASSERT(addonId);
|
||||
MOZ_ASSERT(nsContentUtils::IsSystemPrincipal(GetPrincipal()));
|
||||
|
||||
// If we already have an addon scope object, we know what to use.
|
||||
for (size_t i = 0; i < mAddonScopes.Length(); i++) {
|
||||
if (JS::AddonIdOfObject(js::UncheckedUnwrap(mAddonScopes[i])) == addonId)
|
||||
return mAddonScopes[i];
|
||||
}
|
||||
|
||||
SandboxOptions options;
|
||||
options.wantComponents = true;
|
||||
options.proto = global;
|
||||
options.sameZoneAs = global;
|
||||
options.addonId = JS::StringOfAddonId(addonId);
|
||||
options.writeToGlobalPrototype = true;
|
||||
|
||||
RootedValue v(cx);
|
||||
nsresult rv = CreateSandboxObject(cx, &v, GetPrincipal(), options);
|
||||
NS_ENSURE_SUCCESS(rv, nullptr);
|
||||
mAddonScopes.AppendElement(&v.toObject());
|
||||
|
||||
EnsureCompartmentPrivate(js::UncheckedUnwrap(&v.toObject()))->scope->mIsAddonScope = true;
|
||||
return &v.toObject();
|
||||
}
|
||||
|
||||
JSObject *
|
||||
xpc::GetAddonScope(JSContext *cx, JS::HandleObject contentScope, JSAddonId *addonId)
|
||||
{
|
||||
MOZ_RELEASE_ASSERT(!IsInAddonScope(contentScope));
|
||||
|
||||
if (!addonId || !CompartmentPerAddon()) {
|
||||
return js::GetGlobalForObjectCrossCompartment(contentScope);
|
||||
}
|
||||
|
||||
JSAutoCompartment ac(cx, contentScope);
|
||||
XPCWrappedNativeScope *nativeScope = EnsureCompartmentPrivate(contentScope)->scope;
|
||||
JSObject *scope = nativeScope->EnsureAddonScope(cx, addonId);
|
||||
NS_ENSURE_TRUE(scope, nullptr);
|
||||
|
||||
scope = js::UncheckedUnwrap(scope);
|
||||
JS::ExposeObjectToActiveJS(scope);
|
||||
return scope;
|
||||
}
|
||||
|
||||
XPCWrappedNativeScope::~XPCWrappedNativeScope()
|
||||
{
|
||||
MOZ_COUNT_DTOR(XPCWrappedNativeScope);
|
||||
@ -304,6 +372,8 @@ XPCWrappedNativeScope::~XPCWrappedNativeScope()
|
||||
|
||||
JSRuntime *rt = XPCJSRuntime::Get()->Runtime();
|
||||
mContentXBLScope.finalize(rt);
|
||||
for (size_t i = 0; i < mAddonScopes.Length(); i++)
|
||||
mAddonScopes[i].finalize(rt);
|
||||
mGlobalJSObject.finalize(rt);
|
||||
}
|
||||
|
||||
|
@ -1024,6 +1024,8 @@ public:
|
||||
mGlobalJSObject.trace(trc, "XPCWrappedNativeScope::mGlobalJSObject");
|
||||
if (mContentXBLScope)
|
||||
mContentXBLScope.trace(trc, "XPCWrappedNativeScope::mXBLScope");
|
||||
for (size_t i = 0; i < mAddonScopes.Length(); i++)
|
||||
mAddonScopes[i].trace(trc, "XPCWrappedNativeScope::mAddonScopes");
|
||||
if (mXrayExpandos.initialized())
|
||||
mXrayExpandos.trace(trc);
|
||||
}
|
||||
@ -1101,6 +1103,8 @@ public:
|
||||
// object is wrapped into the compartment of the global.
|
||||
JSObject *EnsureContentXBLScope(JSContext *cx);
|
||||
|
||||
JSObject *EnsureAddonScope(JSContext *cx, JSAddonId *addonId);
|
||||
|
||||
XPCWrappedNativeScope(JSContext *cx, JS::HandleObject aGlobal);
|
||||
|
||||
nsAutoPtr<JSObject2JSObjectMap> mWaiverWrapperMap;
|
||||
@ -1109,6 +1113,8 @@ public:
|
||||
bool AllowContentXBLScope();
|
||||
bool UseContentXBLScope() { return mUseContentXBLScope; }
|
||||
|
||||
bool IsAddonScope() { return mIsAddonScope; }
|
||||
|
||||
protected:
|
||||
virtual ~XPCWrappedNativeScope();
|
||||
|
||||
@ -1136,11 +1142,15 @@ private:
|
||||
// This reference is wrapped into the compartment of mGlobalJSObject.
|
||||
JS::ObjectPtr mContentXBLScope;
|
||||
|
||||
// Lazily created sandboxes for addon code.
|
||||
nsTArray<JS::ObjectPtr> mAddonScopes;
|
||||
|
||||
nsAutoPtr<DOMExpandoSet> mDOMExpandoSet;
|
||||
|
||||
JS::WeakMapPtr<JSObject*, JSObject*> mXrayExpandos;
|
||||
|
||||
bool mIsContentXBLScope;
|
||||
bool mIsAddonScope;
|
||||
|
||||
// For remote XUL domains, we run all XBL in the content scope for compat
|
||||
// reasons (though we sometimes pref this off for automation). We separately
|
||||
|
@ -109,6 +109,12 @@ AllowContentXBLScope(JSCompartment *c);
|
||||
bool
|
||||
UseContentXBLScope(JSCompartment *c);
|
||||
|
||||
bool
|
||||
IsInAddonScope(JSObject *obj);
|
||||
|
||||
JSObject *
|
||||
GetAddonScope(JSContext *cx, JS::HandleObject contentScope, JSAddonId *addonId);
|
||||
|
||||
bool
|
||||
IsSandboxPrototypeProxy(JSObject *obj);
|
||||
|
||||
|
@ -138,6 +138,11 @@ pref("dom.webcrypto.enabled", true);
|
||||
// Whether the UndoManager API is enabled
|
||||
pref("dom.undo_manager.enabled", false);
|
||||
|
||||
// Whether to run add-on code in different compartments from browser code. This
|
||||
// causes a separate compartment for each (addon, global) combination, which may
|
||||
// significantly increase the number of compartments in the system.
|
||||
pref("dom.compartment_per_addon", false);
|
||||
|
||||
// Fastback caching - if this pref is negative, then we calculate the number
|
||||
// of content viewers to cache based on the amount of available memory.
|
||||
pref("browser.sessionhistory.max_total_viewers", -1);
|
||||
|
Loading…
Reference in New Issue
Block a user