зеркало из https://github.com/mozilla/pjs.git
bug 580128 - Fix bugs dealing with transplanting when navigating. r=gal
This commit is contained in:
Родитель
85c8778863
Коммит
d4dbc19ff6
|
@ -1237,6 +1237,13 @@ JS_TransplantWrapper(JSContext *cx, JSObject *wrapper, JSObject *target)
|
|||
* compartment.
|
||||
*/
|
||||
JSCompartment *destination = target->getCompartment();
|
||||
if (wrapper->getCompartment() == destination) {
|
||||
// If the wrapper is in the same compartment as the destination, then
|
||||
// we know that we won't find wrapper in the destination's cross
|
||||
// compartment map and that the same object will continue to work.
|
||||
wrapper->swap(target);
|
||||
return wrapper;
|
||||
}
|
||||
|
||||
JSObject *obj;
|
||||
WrapperMap &map = destination->crossCompartmentWrappers;
|
||||
|
@ -1260,7 +1267,7 @@ JS_TransplantWrapper(JSContext *cx, JSObject *wrapper, JSObject *target)
|
|||
// outer window. They need to be updated to point at the new outer window.
|
||||
// They also might transition between different types of security wrappers
|
||||
// based on whether the new compartment is same origin with them.
|
||||
Value targetv = ObjectValue(*target);
|
||||
Value targetv = ObjectValue(*obj);
|
||||
WrapperVector &vector = cx->runtime->compartments;
|
||||
for (JSCompartment **p = vector.begin(), **end = vector.end(); p != end; ++p) {
|
||||
WrapperMap &pmap = (*p)->crossCompartmentWrappers;
|
||||
|
@ -1268,6 +1275,11 @@ JS_TransplantWrapper(JSContext *cx, JSObject *wrapper, JSObject *target)
|
|||
// We found a wrapper around the outer window!
|
||||
JSObject *wobj = &wp->value.toObject();
|
||||
|
||||
// NB: Can't use wp after this point. We remove wp from the map in
|
||||
// order to ensure that we create a wrapper with the proper guts
|
||||
// for the brain transplant.
|
||||
pmap.remove(wp);
|
||||
|
||||
// First, we wrap it in the new compartment. This will return a
|
||||
// new wrapper.
|
||||
JSAutoEnterCompartment ec;
|
||||
|
@ -1278,14 +1290,23 @@ JS_TransplantWrapper(JSContext *cx, JSObject *wrapper, JSObject *target)
|
|||
// Now, because we need to maintain object identity, we do a brain
|
||||
// transplant on the old object. At the same time, we update the
|
||||
// entry in the compartment's wrapper map to point to the old
|
||||
// wrapper, and remove the old outer window from the wrapper map,
|
||||
// since it is now an obsolete reference.
|
||||
// wrapper.
|
||||
JS_ASSERT(tobj != wobj);
|
||||
wobj->swap(tobj);
|
||||
pmap.put(targetv, ObjectValue(*wobj));
|
||||
pmap.remove(wp);
|
||||
}
|
||||
}
|
||||
|
||||
// Lastly, update the old outer window proxy to point to the new one.
|
||||
{
|
||||
JSAutoEnterCompartment ac;
|
||||
JSObject *tobj = obj;
|
||||
if (!ac.enter(cx, wrapper) || !JS_WrapObject(cx, &tobj))
|
||||
return NULL;
|
||||
wrapper->swap(tobj);
|
||||
wrapper->getCompartment()->crossCompartmentWrappers.put(targetv, wrapperv);
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче