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);
|
NS_ENSURE_TRUE(currentInner, NS_OK);
|
||||||
|
|
||||||
JSObject* obj = currentInner->FastGetGlobalJSObject();
|
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))) {
|
if (obj && !js::IsSystemCompartment(js::GetObjectCompartment(obj))) {
|
||||||
JSContext* cx =
|
JSContext* cx =
|
||||||
nsContentUtils::ThreadJSContextStack()->GetSafeJSContext();
|
nsContentUtils::ThreadJSContextStack()->GetSafeJSContext();
|
||||||
|
|
||||||
JSAutoRequest ar(cx);
|
JSAutoRequest ar(cx);
|
||||||
|
js::NukeCrossCompartmentWrappers(cx,
|
||||||
js::NukeChromeCrossCompartmentWrappersForGlobal(cx, obj,
|
js::ChromeCompartmentsOnly(),
|
||||||
window->IsInnerWindow() ? js::DontNukeForGlobalObject :
|
js::SingleCompartment(js::GetObjectCompartment(obj)),
|
||||||
js::NukeForGlobalObject);
|
window->IsInnerWindow() ? js::DontNukeForGlobalObject :
|
||||||
|
js::NukeForGlobalObject);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -821,9 +821,47 @@ typedef enum NukedGlobalHandling {
|
|||||||
DontNukeForGlobalObject
|
DontNukeForGlobalObject
|
||||||
} NukedGlobalHandling;
|
} 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)
|
extern JS_FRIEND_API(JSBool)
|
||||||
NukeChromeCrossCompartmentWrappersForGlobal(JSContext *cx, JSObject *obj,
|
NukeCrossCompartmentWrappers(JSContext* cx,
|
||||||
NukedGlobalHandling nukeGlobal);
|
const CompartmentFilter& sourceFilter,
|
||||||
|
const CompartmentFilter& targetFilter,
|
||||||
|
NukedGlobalHandling nukeGlobal);
|
||||||
|
|
||||||
} /* namespace js */
|
} /* namespace js */
|
||||||
|
|
||||||
|
@ -1062,20 +1062,20 @@ js::NukeCrossCompartmentWrapper(JSObject *wrapper)
|
|||||||
* option of how to handle the global object.
|
* option of how to handle the global object.
|
||||||
*/
|
*/
|
||||||
JS_FRIEND_API(JSBool)
|
JS_FRIEND_API(JSBool)
|
||||||
js::NukeChromeCrossCompartmentWrappersForGlobal(JSContext *cx, JSObject *obj,
|
js::NukeCrossCompartmentWrappers(JSContext* cx,
|
||||||
js::NukedGlobalHandling nukeGlobal)
|
const CompartmentFilter& sourceFilter,
|
||||||
|
const CompartmentFilter& targetFilter,
|
||||||
|
js::NukedGlobalHandling nukeGlobal)
|
||||||
{
|
{
|
||||||
CHECK_REQUEST(cx);
|
CHECK_REQUEST(cx);
|
||||||
|
|
||||||
JSRuntime *rt = cx->runtime;
|
JSRuntime *rt = cx->runtime;
|
||||||
JSObject *global = &obj->global();
|
|
||||||
|
|
||||||
// Iterate through scopes looking for system cross compartment wrappers
|
// Iterate through scopes looking for system cross compartment wrappers
|
||||||
// that point to an object that shares a global with obj.
|
// that point to an object that shares a global with obj.
|
||||||
|
|
||||||
for (CompartmentsIter c(rt); !c.done(); c.next()) {
|
for (CompartmentsIter c(rt); !c.done(); c.next()) {
|
||||||
// Skip non-system compartments because this breaks the web.
|
// Skip non-system compartments because this breaks the web.
|
||||||
if (!js::IsSystemCompartment(c))
|
if (!sourceFilter.match(c))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Iterate the wrappers looking for anything interesting.
|
// 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 *wobj = &e.front().value.get().toObject();
|
||||||
JSObject *wrapped = UnwrapObject(wobj, false);
|
JSObject *wrapped = UnwrapObject(wobj, false);
|
||||||
|
|
||||||
if (nukeGlobal == DontNukeForGlobalObject && wrapped == global)
|
if (nukeGlobal == DontNukeForGlobalObject && wrapped->isGlobal())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (&wrapped->global() == global) {
|
if (targetFilter.match(wrapped->compartment())) {
|
||||||
// We found a wrapper to nuke.
|
// We found a wrapper to nuke.
|
||||||
e.removeFront();
|
e.removeFront();
|
||||||
NukeCrossCompartmentWrapper(wobj);
|
NukeCrossCompartmentWrapper(wobj);
|
||||||
|
@ -340,37 +340,6 @@ RemapAllWrappersForObject(JSContext *cx, JSObject *oldTarget,
|
|||||||
|
|
||||||
// API to recompute all cross-compartment wrappers whose source and target
|
// API to recompute all cross-compartment wrappers whose source and target
|
||||||
// match the given filters.
|
// 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)
|
JS_FRIEND_API(bool)
|
||||||
RecomputeWrappers(JSContext *cx, const CompartmentFilter &sourceFilter,
|
RecomputeWrappers(JSContext *cx, const CompartmentFilter &sourceFilter,
|
||||||
const CompartmentFilter &targetFilter);
|
const CompartmentFilter &targetFilter);
|
||||||
|
Loading…
Reference in New Issue
Block a user