mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-21 01:05:45 +00:00
Bug 769273 - part2: Refactoring NukeChromeCrossCompartmentWrappersForGlobal. r=bholley
This commit is contained in:
parent
1c23b37d56
commit
7a00ad07d8
@ -6860,16 +6860,17 @@ public:
|
||||
NS_ENSURE_TRUE(currentInner, NS_OK);
|
||||
|
||||
JSObject* obj = currentInner->FastGetGlobalJSObject();
|
||||
// We only want to nuke wrappers for chrome->content case
|
||||
// We only want to nuke wrappers for the chrome->content case
|
||||
if (obj && !js::IsSystemCompartment(js::GetObjectCompartment(obj))) {
|
||||
JSContext* cx =
|
||||
nsContentUtils::ThreadJSContextStack()->GetSafeJSContext();
|
||||
|
||||
JSAutoRequest ar(cx);
|
||||
|
||||
js::NukeChromeCrossCompartmentWrappersForGlobal(cx, obj,
|
||||
window->IsInnerWindow() ? js::DontNukeForGlobalObject :
|
||||
js::NukeForGlobalObject);
|
||||
js::NukeCrossCompartmentWrappers(cx,
|
||||
js::ChromeCompartmentsOnly(),
|
||||
js::SingleCompartment(js::GetObjectCompartment(obj)),
|
||||
window->IsInnerWindow() ? js::DontNukeForGlobalObject :
|
||||
js::NukeForGlobalObject);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -821,9 +821,47 @@ typedef enum NukedGlobalHandling {
|
||||
DontNukeForGlobalObject
|
||||
} NukedGlobalHandling;
|
||||
|
||||
// These filters are designed to be ephemeral stack classes, and thus don't
|
||||
// do any rooting or holding of their members.
|
||||
struct CompartmentFilter {
|
||||
virtual bool match(JSCompartment *c) const = 0;
|
||||
};
|
||||
|
||||
struct AllCompartments : public CompartmentFilter {
|
||||
virtual bool match(JSCompartment *c) const { return true; };
|
||||
};
|
||||
|
||||
struct ContentCompartmentsOnly : public CompartmentFilter {
|
||||
virtual bool match(JSCompartment *c) const {
|
||||
return !IsSystemCompartment(c);
|
||||
};
|
||||
};
|
||||
|
||||
struct ChromeCompartmentsOnly : public CompartmentFilter {
|
||||
virtual bool match(JSCompartment *c) const {
|
||||
return IsSystemCompartment(c);
|
||||
};
|
||||
};
|
||||
|
||||
struct SingleCompartment : public CompartmentFilter {
|
||||
JSCompartment *ours;
|
||||
SingleCompartment(JSCompartment *c) : ours(c) {};
|
||||
virtual bool match(JSCompartment *c) const { return c == ours; };
|
||||
};
|
||||
|
||||
struct CompartmentsWithPrincipals : public CompartmentFilter {
|
||||
JSPrincipals *principals;
|
||||
CompartmentsWithPrincipals(JSPrincipals *p) : principals(p) {};
|
||||
virtual bool match(JSCompartment *c) const {
|
||||
return JS_GetCompartmentPrincipals(c) == principals;
|
||||
};
|
||||
};
|
||||
|
||||
extern JS_FRIEND_API(JSBool)
|
||||
NukeChromeCrossCompartmentWrappersForGlobal(JSContext *cx, JSObject *obj,
|
||||
NukedGlobalHandling nukeGlobal);
|
||||
NukeCrossCompartmentWrappers(JSContext* cx,
|
||||
const CompartmentFilter& sourceFilter,
|
||||
const CompartmentFilter& targetFilter,
|
||||
NukedGlobalHandling nukeGlobal);
|
||||
|
||||
} /* namespace js */
|
||||
|
||||
|
@ -1062,20 +1062,20 @@ js::NukeCrossCompartmentWrapper(JSObject *wrapper)
|
||||
* option of how to handle the global object.
|
||||
*/
|
||||
JS_FRIEND_API(JSBool)
|
||||
js::NukeChromeCrossCompartmentWrappersForGlobal(JSContext *cx, JSObject *obj,
|
||||
js::NukedGlobalHandling nukeGlobal)
|
||||
js::NukeCrossCompartmentWrappers(JSContext* cx,
|
||||
const CompartmentFilter& sourceFilter,
|
||||
const CompartmentFilter& targetFilter,
|
||||
js::NukedGlobalHandling nukeGlobal)
|
||||
{
|
||||
CHECK_REQUEST(cx);
|
||||
|
||||
JSRuntime *rt = cx->runtime;
|
||||
JSObject *global = &obj->global();
|
||||
|
||||
// Iterate through scopes looking for system cross compartment wrappers
|
||||
// that point to an object that shares a global with obj.
|
||||
|
||||
for (CompartmentsIter c(rt); !c.done(); c.next()) {
|
||||
// Skip non-system compartments because this breaks the web.
|
||||
if (!js::IsSystemCompartment(c))
|
||||
if (!sourceFilter.match(c))
|
||||
continue;
|
||||
|
||||
// Iterate the wrappers looking for anything interesting.
|
||||
@ -1090,10 +1090,10 @@ js::NukeChromeCrossCompartmentWrappersForGlobal(JSContext *cx, JSObject *obj,
|
||||
JSObject *wobj = &e.front().value.get().toObject();
|
||||
JSObject *wrapped = UnwrapObject(wobj, false);
|
||||
|
||||
if (nukeGlobal == DontNukeForGlobalObject && wrapped == global)
|
||||
if (nukeGlobal == DontNukeForGlobalObject && wrapped->isGlobal())
|
||||
continue;
|
||||
|
||||
if (&wrapped->global() == global) {
|
||||
if (targetFilter.match(wrapped->compartment())) {
|
||||
// We found a wrapper to nuke.
|
||||
e.removeFront();
|
||||
NukeCrossCompartmentWrapper(wobj);
|
||||
|
@ -340,37 +340,6 @@ RemapAllWrappersForObject(JSContext *cx, JSObject *oldTarget,
|
||||
|
||||
// API to recompute all cross-compartment wrappers whose source and target
|
||||
// match the given filters.
|
||||
//
|
||||
// These filters are designed to be ephemeral stack classes, and thus don't
|
||||
// do any rooting or holding of their members.
|
||||
struct CompartmentFilter {
|
||||
virtual bool match(JSCompartment *c) const = 0;
|
||||
};
|
||||
|
||||
struct AllCompartments : public CompartmentFilter {
|
||||
virtual bool match(JSCompartment *c) const { return true; }
|
||||
};
|
||||
|
||||
struct ContentCompartmentsOnly : public CompartmentFilter {
|
||||
virtual bool match(JSCompartment *c) const {
|
||||
return !IsSystemCompartment(c);
|
||||
}
|
||||
};
|
||||
|
||||
struct SingleCompartment : public CompartmentFilter {
|
||||
JSCompartment *ours;
|
||||
SingleCompartment(JSCompartment *c) : ours(c) {}
|
||||
virtual bool match(JSCompartment *c) const { return c == ours; }
|
||||
};
|
||||
|
||||
struct CompartmentsWithPrincipals : public CompartmentFilter {
|
||||
JSPrincipals *principals;
|
||||
CompartmentsWithPrincipals(JSPrincipals *p) : principals(p) {}
|
||||
virtual bool match(JSCompartment *c) const {
|
||||
return JS_GetCompartmentPrincipals(c) == principals;
|
||||
}
|
||||
};
|
||||
|
||||
JS_FRIEND_API(bool)
|
||||
RecomputeWrappers(JSContext *cx, const CompartmentFilter &sourceFilter,
|
||||
const CompartmentFilter &targetFilter);
|
||||
|
Loading…
Reference in New Issue
Block a user