Bug 739796 - Make same-origin cross-compartment Location object access go through the LW in the host compartment. r=gal

--HG--
extra : rebase_source : d5e07d4628bfd5990d127b4316219a43c4e0de88
This commit is contained in:
Bobby Holley 2012-04-05 12:21:12 -07:00
parent b1e579a168
commit b36c773a23

View File

@ -373,23 +373,45 @@ WrapperFactory::Rewrap(JSContext *cx, JSObject *obj, JSObject *wrappedProto, JSO
} else if (AccessCheck::isSameOrigin(origin, target)) {
// For the same-origin case we use a transparent wrapper, unless one
// of the following is true:
// * The wrapper is a Location object.
// * The wrapper is flagged as needing a SOW.
// * The object is flagged as needing a SOW.
// * The object is a location object.
// * The context compartment specifically requested Xray vision into
// same-origin compartments.
//
// The first two cases always require a security wrapper for non-chrome
// access, regardless of the origin of the object.
//
// The Location case is a bit tricky. Because the security characteristics
// depend on the current outer window, we always have a security wrapper
// around locations, same-compartment or cross-compartment. We would
// normally just use an identical security policy and just switch between
// Wrapper and CrossCompartmentWrapper to differentiate the cases (LW/XLW).
// However, there's an added wrinkle that same-origin-but-cross-compartment
// scripts expect to be able to see expandos on each others' location
// objects. So if all cross-compartment access used XLWs, then the expandos
// would live on the per-compartment XrayWrapper expando object, and would
// not be shared. So to make sure that expandos work correctly in the
// same-origin case, we need to use a transparent CrossCompartmentWrapper
// to the LW in the host compartment, rather than an XLW directly to the
// Location object. This still doesn't share expandos in the
// document.domain case, but that's probably fine. Double-wrapping sucks,
// but it's kind of unavoidable here.
XrayType type;
if (AccessCheck::needsSystemOnlyWrapper(obj)) {
wrapper = &FilteringWrapper<CrossCompartmentSecurityWrapper,
OnlyIfSubjectIsSystem>::singleton;
} else if (IsLocationObject(obj)) {
typedef XrayWrapper<CrossCompartmentSecurityWrapper> Xray;
usingXray = true;
wrapper = &FilteringWrapper<Xray, LocationPolicy>::singleton;
} else if (!targetdata || !targetdata->wantXrays ||
(type = GetXrayType(obj)) == NotXray) {
// Do the double-wrapping if need be.
if (IsLocationObject(obj)) {
JSAutoEnterCompartment ac;
if (!ac.enter(cx, obj))
return nsnull;
XPCWrappedNative *wn = GetWrappedNative(cx, obj);
if (!wn)
return nsnull;
obj = wn->GetSameCompartmentSecurityWrapper(cx);
}
wrapper = &CrossCompartmentWrapper::singleton;
} else if (type == XrayForDOMObject) {
wrapper = &XrayDOM::singleton;