mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Backed out changesets 63671ebfa2dd and da3d272ad1c2 (bug 1164011) for frequent xpc::InterposeProperty crashes.
This commit is contained in:
parent
ca1661674b
commit
004203a4be
@ -436,7 +436,6 @@
|
||||
@RESPATH@/components/nsUpdateTimerManager.js
|
||||
@RESPATH@/components/addoncompat.manifest
|
||||
@RESPATH@/components/multiprocessShims.js
|
||||
@RESPATH@/components/defaultShims.js
|
||||
@RESPATH@/components/remoteTagService.js
|
||||
@RESPATH@/components/pluginGlue.manifest
|
||||
@RESPATH@/components/ProcessSingleton.manifest
|
||||
|
@ -20,7 +20,7 @@
|
||||
* property, it should return a replacement property descriptor for it. If not,
|
||||
* it should return null.
|
||||
*/
|
||||
[scriptable,uuid(d05cc5fd-ad88-41a6-854c-36fd94d69ddb)]
|
||||
[scriptable,uuid(215353cb-6e77-462f-a791-6891f42e593f)]
|
||||
interface nsIAddonInterposition : nsISupports
|
||||
{
|
||||
/**
|
||||
@ -54,14 +54,4 @@ interface nsIAddonInterposition : nsISupports
|
||||
in jsval originalFunc,
|
||||
in jsval originalThis,
|
||||
in jsval args);
|
||||
|
||||
/**
|
||||
* For the first time when the interposition is registered the engine
|
||||
* calls getWhitelist and expects an array of strings. The strings are
|
||||
* the name of properties the interposition wants interposeProperty
|
||||
* to be called. It can be an empty array.
|
||||
* Note: for CPOWs interposeProperty is always called regardless if
|
||||
* the name of the property is on the whitelist or not.
|
||||
*/
|
||||
jsval getWhitelist();
|
||||
};
|
||||
|
@ -32,7 +32,6 @@
|
||||
#include "nsWindowMemoryReporter.h"
|
||||
#include "nsDOMClassInfo.h"
|
||||
#include "ShimInterfaceInfo.h"
|
||||
#include "nsIAddonInterposition.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace JS;
|
||||
@ -3491,9 +3490,8 @@ nsXPCComponents_Utils::SetAddonInterposition(const nsACString& addonIdStr,
|
||||
JSAddonId* addonId = xpc::NewAddonId(cx, addonIdStr);
|
||||
if (!addonId)
|
||||
return NS_ERROR_FAILURE;
|
||||
if (!XPCWrappedNativeScope::SetAddonInterposition(cx, addonId, interposition))
|
||||
if (!XPCWrappedNativeScope::SetAddonInterposition(addonId, interposition))
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -27,7 +27,6 @@ using namespace JS;
|
||||
XPCWrappedNativeScope* XPCWrappedNativeScope::gScopes = nullptr;
|
||||
XPCWrappedNativeScope* XPCWrappedNativeScope::gDyingScopes = nullptr;
|
||||
XPCWrappedNativeScope::InterpositionMap* XPCWrappedNativeScope::gInterpositionMap = nullptr;
|
||||
InterpositionWhitelistArray* XPCWrappedNativeScope::gInterpositionWhitelists = nullptr;
|
||||
|
||||
NS_IMPL_ISUPPORTS(XPCWrappedNativeScope::ClearInterpositionsObserver, nsIObserver)
|
||||
|
||||
@ -47,11 +46,6 @@ XPCWrappedNativeScope::ClearInterpositionsObserver::Observe(nsISupports* subject
|
||||
gInterpositionMap = nullptr;
|
||||
}
|
||||
|
||||
if (gInterpositionWhitelists) {
|
||||
delete gInterpositionWhitelists;
|
||||
gInterpositionWhitelists = nullptr;
|
||||
}
|
||||
|
||||
nsContentUtils::UnregisterShutdownObserver(this);
|
||||
return NS_OK;
|
||||
}
|
||||
@ -149,8 +143,6 @@ XPCWrappedNativeScope::XPCWrappedNativeScope(JSContext* cx,
|
||||
"extensions.interposition.enabled", false);
|
||||
if (interpositionEnabled) {
|
||||
mInterposition = do_GetService("@mozilla.org/addons/default-addon-shims;1");
|
||||
MOZ_ASSERT(mInterposition);
|
||||
UpdateInterpositionWhitelist(cx, mInterposition);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -764,8 +756,7 @@ XPCWrappedNativeScope::SetExpandoChain(JSContext* cx, HandleObject target,
|
||||
}
|
||||
|
||||
/* static */ bool
|
||||
XPCWrappedNativeScope::SetAddonInterposition(JSContext* cx,
|
||||
JSAddonId* addonId,
|
||||
XPCWrappedNativeScope::SetAddonInterposition(JSAddonId* addonId,
|
||||
nsIAddonInterposition* interp)
|
||||
{
|
||||
if (!gInterpositionMap) {
|
||||
@ -773,17 +764,14 @@ XPCWrappedNativeScope::SetAddonInterposition(JSContext* cx,
|
||||
gInterpositionMap->init();
|
||||
|
||||
// Make sure to clear the map at shutdown.
|
||||
// Note: this will take care of gInterpositionWhitelists too.
|
||||
nsContentUtils::RegisterShutdownObserver(new ClearInterpositionsObserver());
|
||||
}
|
||||
if (interp) {
|
||||
bool ok = gInterpositionMap->put(addonId, interp);
|
||||
NS_ENSURE_TRUE(ok, false);
|
||||
UpdateInterpositionWhitelist(cx, interp);
|
||||
return gInterpositionMap->put(addonId, interp);
|
||||
} else {
|
||||
gInterpositionMap->remove(addonId);
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIAddonInterposition>
|
||||
@ -792,103 +780,6 @@ XPCWrappedNativeScope::GetInterposition()
|
||||
return mInterposition;
|
||||
}
|
||||
|
||||
/* static */ InterpositionWhitelist*
|
||||
XPCWrappedNativeScope::GetInterpositionWhitelist(nsIAddonInterposition* interposition)
|
||||
{
|
||||
if (!gInterpositionWhitelists)
|
||||
return nullptr;
|
||||
|
||||
InterpositionWhitelistArray& wls = *gInterpositionWhitelists;
|
||||
for (size_t i = 0; i < wls.Length(); i++) {
|
||||
if (wls[i].interposition == interposition)
|
||||
return &wls[i].whitelist;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/* static */ bool
|
||||
XPCWrappedNativeScope::UpdateInterpositionWhitelist(JSContext* cx,
|
||||
nsIAddonInterposition* interposition)
|
||||
{
|
||||
// We want to set the interpostion whitelist only once.
|
||||
InterpositionWhitelist* whitelist = GetInterpositionWhitelist(interposition);
|
||||
if (whitelist)
|
||||
return true;
|
||||
|
||||
// The hashsets in gInterpositionWhitelists do not have a copy constructor so
|
||||
// a reallocation for the array will lead to a memory corruption. If you
|
||||
// need more interpositions, change the capacity of the array please.
|
||||
static const size_t MAX_INTERPOSITION = 8;
|
||||
if (!gInterpositionWhitelists)
|
||||
gInterpositionWhitelists = new InterpositionWhitelistArray(MAX_INTERPOSITION);
|
||||
|
||||
MOZ_RELEASE_ASSERT(MAX_INTERPOSITION > gInterpositionWhitelists->Length() + 1);
|
||||
InterpositionWhitelistPair* newPair = gInterpositionWhitelists->AppendElement();
|
||||
newPair->interposition = interposition;
|
||||
newPair->whitelist.init();
|
||||
whitelist = &newPair->whitelist;
|
||||
|
||||
RootedValue whitelistVal(cx);
|
||||
nsresult rv = interposition->GetWhitelist(&whitelistVal);
|
||||
if (NS_FAILED(rv)) {
|
||||
JS_ReportError(cx, "Could not get the whitelist from the interposition.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!whitelistVal.isObject()) {
|
||||
JS_ReportError(cx, "Whitelist must be an array.");
|
||||
return false;
|
||||
}
|
||||
|
||||
// We want to enter the whitelist's compartment to avoid any wrappers.
|
||||
// To be on the safe side let's make sure that it's a system compartment
|
||||
// and we don't accidentally trigger some content function here by parsing
|
||||
// the whitelist object.
|
||||
RootedObject whitelistObj(cx, &whitelistVal.toObject());
|
||||
whitelistObj = js::UncheckedUnwrap(whitelistObj);
|
||||
if (!AccessCheck::isChrome(whitelistObj)) {
|
||||
JS_ReportError(cx, "Whitelist must be from system scope.");
|
||||
return false;
|
||||
}
|
||||
|
||||
{
|
||||
JSAutoCompartment ac(cx, whitelistObj);
|
||||
|
||||
uint32_t length;
|
||||
if (!JS_IsArrayObject(cx, whitelistObj) ||
|
||||
!JS_GetArrayLength(cx, whitelistObj, &length)) {
|
||||
JS_ReportError(cx, "Whitelist must be an array.");
|
||||
return false;
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < length; i++) {
|
||||
RootedValue idval(cx);
|
||||
if (!JS_GetElement(cx, whitelistObj, i, &idval))
|
||||
return false;
|
||||
|
||||
if (!idval.isString()) {
|
||||
JS_ReportError(cx, "Whitelist must contain strings only.");
|
||||
return false;
|
||||
}
|
||||
|
||||
RootedString str(cx, idval.toString());
|
||||
str = JS_InternJSString(cx, str);
|
||||
if (!str) {
|
||||
JS_ReportError(cx, "String internization failed.");
|
||||
return false;
|
||||
}
|
||||
|
||||
// By internizing the id's we ensure that they won't get
|
||||
// GCed so we can use them as hash keys.
|
||||
jsid id = INTERNED_STRING_TO_JSID(cx, str);
|
||||
whitelist->put(JSID_BITS(id));
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
// static
|
||||
|
@ -1360,14 +1360,17 @@ bool
|
||||
SetAddonInterposition(const nsACString& addonIdStr, nsIAddonInterposition* interposition)
|
||||
{
|
||||
JSAddonId* addonId;
|
||||
// We enter the junk scope just to allocate a string, which actually will go
|
||||
// in the system zone.
|
||||
AutoJSAPI jsapi;
|
||||
jsapi.Init(xpc::PrivilegedJunkScope());
|
||||
addonId = NewAddonId(jsapi.cx(), addonIdStr);
|
||||
if (!addonId)
|
||||
return false;
|
||||
return XPCWrappedNativeScope::SetAddonInterposition(jsapi.cx(), addonId, interposition);
|
||||
{
|
||||
// We enter the junk scope just to allocate a string, which actually will go
|
||||
// in the system zone.
|
||||
AutoJSAPI jsapi;
|
||||
jsapi.Init(xpc::PrivilegedJunkScope());
|
||||
addonId = NewAddonId(jsapi.cx(), addonIdStr);
|
||||
if (!addonId)
|
||||
return false;
|
||||
}
|
||||
|
||||
return XPCWrappedNativeScope::SetAddonInterposition(addonId, interposition);
|
||||
}
|
||||
|
||||
} // namespace xpc
|
||||
|
@ -1018,17 +1018,6 @@ static inline bool IS_PROTO_CLASS(const js::Class* clazz)
|
||||
clazz == &XPC_WN_ModsAllowed_NoCall_Proto_JSClass;
|
||||
}
|
||||
|
||||
typedef js::HashSet<uint64_t,
|
||||
js::DefaultHasher<uint64_t>,
|
||||
js::SystemAllocPolicy> InterpositionWhitelist;
|
||||
|
||||
struct InterpositionWhitelistPair {
|
||||
nsIAddonInterposition* interposition;
|
||||
InterpositionWhitelist whitelist;
|
||||
};
|
||||
|
||||
typedef nsTArray<InterpositionWhitelistPair> InterpositionWhitelistArray;
|
||||
|
||||
/***************************************************************************/
|
||||
// XPCWrappedNativeScope is one-to-one with a JS global object.
|
||||
|
||||
@ -1198,14 +1187,9 @@ public:
|
||||
bool HasInterposition() { return mInterposition; }
|
||||
nsCOMPtr<nsIAddonInterposition> GetInterposition();
|
||||
|
||||
static bool SetAddonInterposition(JSContext* cx,
|
||||
JSAddonId* addonId,
|
||||
static bool SetAddonInterposition(JSAddonId* addonId,
|
||||
nsIAddonInterposition* interp);
|
||||
|
||||
static InterpositionWhitelist* GetInterpositionWhitelist(nsIAddonInterposition* interposition);
|
||||
static bool UpdateInterpositionWhitelist(JSContext* cx,
|
||||
nsIAddonInterposition* interposition);
|
||||
|
||||
void SetAddonCallInterposition() { mHasCallInterpositions = true; }
|
||||
bool HasCallInterposition() { return mHasCallInterpositions; };
|
||||
|
||||
@ -1228,8 +1212,6 @@ private:
|
||||
|
||||
static InterpositionMap* gInterpositionMap;
|
||||
|
||||
static InterpositionWhitelistArray* gInterpositionWhitelists;
|
||||
|
||||
XPCJSRuntime* mRuntime;
|
||||
Native2WrappedNativeMap* mWrappedNativeMap;
|
||||
ClassInfo2WrappedNativeProtoMap* mWrappedNativeProtoMap;
|
||||
|
@ -34,11 +34,6 @@ let TestInterposition = {
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIAddonInterposition,
|
||||
Ci.nsISupportsWeakReference]),
|
||||
|
||||
getWhitelist: function() {
|
||||
return ["abcxyz", "utils", "dataprop", "getterprop", "setterprop",
|
||||
"objprop", "defineprop", "configurableprop"];
|
||||
},
|
||||
|
||||
interposeProperty: function(addonId, target, iid, prop) {
|
||||
do_check_eq(addonId, ADDONID);
|
||||
do_check_eq(gExpectedProp, prop);
|
||||
|
@ -29,12 +29,11 @@ InterposeProperty(JSContext* cx, HandleObject target, const nsIID* iid, HandleId
|
||||
// wrapped natives.
|
||||
RootedObject unwrapped(cx, UncheckedUnwrap(target));
|
||||
const js::Class* clasp = js::GetObjectClass(unwrapped);
|
||||
bool isCPOW = jsipc::IsWrappedCPOW(unwrapped);
|
||||
if (!mozilla::dom::IsDOMClass(clasp) &&
|
||||
!IS_WN_CLASS(clasp) &&
|
||||
!IS_PROTO_CLASS(clasp) &&
|
||||
clasp != &OuterWindowProxyClass &&
|
||||
!isCPOW) {
|
||||
!jsipc::IsWrappedCPOW(unwrapped)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -42,13 +41,6 @@ InterposeProperty(JSContext* cx, HandleObject target, const nsIID* iid, HandleId
|
||||
MOZ_ASSERT(scope->HasInterposition());
|
||||
|
||||
nsCOMPtr<nsIAddonInterposition> interp = scope->GetInterposition();
|
||||
InterpositionWhitelist* wl = XPCWrappedNativeScope::GetInterpositionWhitelist(interp);
|
||||
MOZ_ASSERT(wl);
|
||||
// We do InterposeProperty only if the id is on the whitelist of the interpostion
|
||||
// or if the target is a CPOW.
|
||||
if (!wl->has(JSID_BITS(id.get())) && !isCPOW)
|
||||
return true;
|
||||
|
||||
JSAddonId* addonId = AddonIdOfObject(target);
|
||||
RootedValue addonIdValue(cx, StringValue(StringOfAddonId(addonId)));
|
||||
RootedValue prop(cx, IdToValue(id));
|
||||
|
@ -22,10 +22,6 @@ DefaultInterpositionService.prototype = {
|
||||
classID: Components.ID("{50bc93ce-602a-4bef-bf3a-61fc749c4caf}"),
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIAddonInterposition, Ci.nsISupportsWeakReference]),
|
||||
|
||||
getWhitelist: function() {
|
||||
return [];
|
||||
},
|
||||
|
||||
interposeProperty: function(addon, target, iid, prop) {
|
||||
return null;
|
||||
},
|
||||
|
@ -8,7 +8,6 @@ TEST_DIRS += ['tests']
|
||||
|
||||
EXTRA_COMPONENTS += [
|
||||
'addoncompat.manifest',
|
||||
'defaultShims.js',
|
||||
'multiprocessShims.js',
|
||||
'remoteTagService.js',
|
||||
]
|
||||
|
@ -70,42 +70,12 @@ function AddonInterpositionService()
|
||||
// kinds of objects.
|
||||
this._interfaceInterpositions = RemoteAddonsParent.getInterfaceInterpositions();
|
||||
this._taggedInterpositions = RemoteAddonsParent.getTaggedInterpositions();
|
||||
|
||||
let wl = [];
|
||||
for (let v in this._interfaceInterpositions) {
|
||||
let interp = this._interfaceInterpositions[v];
|
||||
wl.push(...Object.getOwnPropertyNames(interp.methods));
|
||||
wl.push(...Object.getOwnPropertyNames(interp.getters));
|
||||
wl.push(...Object.getOwnPropertyNames(interp.setters));
|
||||
}
|
||||
|
||||
for (let v in this._taggedInterpositions) {
|
||||
let interp = this._taggedInterpositions[v];
|
||||
wl.push(...Object.getOwnPropertyNames(interp.methods));
|
||||
wl.push(...Object.getOwnPropertyNames(interp.getters));
|
||||
wl.push(...Object.getOwnPropertyNames(interp.setters));
|
||||
}
|
||||
|
||||
let nameSet = new Set();
|
||||
wl = wl.filter(function(item) {
|
||||
if (nameSet.has(item))
|
||||
return true;
|
||||
|
||||
nameSet.add(item);
|
||||
return true;
|
||||
});
|
||||
|
||||
this._whitelist = wl;
|
||||
}
|
||||
|
||||
AddonInterpositionService.prototype = {
|
||||
classID: Components.ID("{1363d5f0-d95e-11e3-9c1a-0800200c9a66}"),
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIAddonInterposition, Ci.nsISupportsWeakReference]),
|
||||
|
||||
getWhitelist: function() {
|
||||
return this._whitelist;
|
||||
},
|
||||
|
||||
// When the interface is not known for a method call, this code
|
||||
// determines the type of the target object.
|
||||
getObjectTag: function(target) {
|
||||
|
Loading…
Reference in New Issue
Block a user