author | Boris Zbarsky <bzbarsky@mit.edu> |
Wed, 29 Jan 2014 22:34:25 -0800 | |
changeset 181964 | 78767e93ff146527b5139896888fd897a7d4d277 |
parent 181963 | b9c5659550c67aafa073e6509c4aa014dfd45109 |
child 181965 | af39c4df306ffd7f978d0e0d475e4678aa91f3c8 |
push id | 3343 |
push user | ffxbld |
push date | Mon, 17 Mar 2014 21:55:32 +0000 |
treeherder | mozilla-beta@2f7d3415f79f [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | bholley |
bugs | 965144 |
milestone | 29.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/js/xpconnect/wrappers/XrayWrapper.cpp +++ b/js/xpconnect/wrappers/XrayWrapper.cpp @@ -1,8 +1,9 @@ + /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- * vim: set ts=4 sw=4 et tw=99 ft=cpp: * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "XrayWrapper.h" @@ -16,16 +17,17 @@ #include "XPCWrapper.h" #include "xpcprivate.h" #include "jsapi.h" #include "jsprf.h" #include "nsJSUtils.h" #include "mozilla/dom/BindingUtils.h" +#include "mozilla/dom/WindowBinding.h" #include "nsGlobalWindow.h" using namespace mozilla::dom; using namespace JS; using namespace mozilla; using js::Wrapper; using js::IsCrossCompartmentWrapper; @@ -658,30 +660,36 @@ XPCWrappedNativeXrayTraits::resolveDOMCo } if (pobj && !JS_GetPropertyDescriptorById(cx, holder, id, 0, desc)) return false; return true; } -template <typename T> -static T* -As(JSObject *wrapper) +static nsGlobalWindow* +AsWindow(JSContext *cx, JSObject *wrapper) { - XPCWrappedNative *wn = XPCWrappedNativeXrayTraits::getWN(wrapper); - nsCOMPtr<T> native = do_QueryWrappedNative(wn); - return native; + nsGlobalWindow* win; + // We want to use our target object here, since we don't want to be + // doing a security check while unwrapping. + JSObject* target = XrayTraits::getTargetObject(wrapper); + nsresult rv = UNWRAP_OBJECT(Window, target, win); + if (NS_SUCCEEDED(rv)) + return win; + + nsCOMPtr<nsPIDOMWindow> piWin = do_QueryInterface( + nsContentUtils::XPConnect()->GetNativeOfWrapper(cx, target)); + return static_cast<nsGlobalWindow*>(piWin.get()); } -template <typename T> static bool -Is(JSObject *wrapper) +IsWindow(JSContext *cx, JSObject *wrapper) { - return !!As<T>(wrapper); + return !!AsWindow(cx, wrapper); } static nsQueryInterface do_QueryInterfaceNative(JSContext* cx, HandleObject wrapper); void XPCWrappedNativeXrayTraits::preserveWrapper(JSObject *target) { @@ -716,17 +724,17 @@ XPCWrappedNativeXrayTraits::resolveNativ // The |controllers| property is accessible as a [ChromeOnly] property on // Window.WebIDL, and [noscript] in XPIDL. Chrome needs to see this over // Xray, so we need to special-case it until we move |Window| to WebIDL. nsGlobalWindow *win = nullptr; if (id == GetRTIdByIndex(cx, XPCJSRuntime::IDX_CONTROLLERS) && AccessCheck::isChrome(wrapper) && - (win = static_cast<nsGlobalWindow*>(As<nsPIDOMWindow>(wrapper)))) + (win = AsWindow(cx, wrapper))) { nsCOMPtr<nsIControllers> c; nsresult rv = win->GetControllers(getter_AddRefs(c)); if (NS_SUCCEEDED(rv) && c) { rv = nsXPConnect::XPConnect()->WrapNativeToJSVal(cx, CurrentGlobalOrNull(cx), c, nullptr, nullptr, true, desc.value()); } @@ -884,32 +892,31 @@ XPCWrappedNativeXrayTraits::resolveOwnPr bool ok = XrayTraits::resolveOwnProperty(cx, jsWrapper, wrapper, holder, id, desc, flags); if (!ok || desc.object()) return ok; // Check for indexed access on a window. int32_t index = GetArrayIndexFromId(cx, id); if (IsArrayIndex(index)) { - nsGlobalWindow* win = - static_cast<nsGlobalWindow*>(As<nsPIDOMWindow>(wrapper)); + nsGlobalWindow* win = AsWindow(cx, wrapper); // Note: As() unwraps outer windows to get to the inner window. if (win) { bool unused; nsCOMPtr<nsIDOMWindow> subframe = win->IndexedGetter(index, unused); if (subframe) { nsGlobalWindow* global = static_cast<nsGlobalWindow*>(subframe.get()); global->EnsureInnerWindow(); JSObject* obj = global->FastGetGlobalJSObject(); if (MOZ_UNLIKELY(!obj)) { // It's gone? return xpc::Throw(cx, NS_ERROR_FAILURE); } desc.value().setObject(*obj); - mozilla::dom::FillPropertyDescriptor(desc, wrapper, true); + FillPropertyDescriptor(desc, wrapper, true); return JS_WrapPropertyDescriptor(cx, desc); } } } // Xray wrappers don't use the regular wrapper hierarchy, so we should be // in the wrapper's compartment here, not the wrappee. MOZ_ASSERT(js::IsObjectInContextCompartment(wrapper, cx)); @@ -974,17 +981,17 @@ XPCWrappedNativeXrayTraits::defineProper *defined = true; return JS_DefinePropertyById(cx, holder, id, desc.value(), desc.getter(), desc.setter(), desc.attributes()); } // Check for an indexed property on a Window. If that's happening, do // nothing but claim we defined it so it won't get added as an expando. int32_t index = GetArrayIndexFromId(cx, id); - if (IsArrayIndex(index) && Is<nsIDOMWindow>(wrapper)) { + if (IsArrayIndex(index) && IsWindow(cx, wrapper)) { *defined = true; return true; } return true; } bool @@ -1097,16 +1104,39 @@ DOMXrayTraits::resolveOwnProperty(JSCont MutableHandle<JSPropertyDescriptor> desc, unsigned flags) { // Call the common code. bool ok = XrayTraits::resolveOwnProperty(cx, jsWrapper, wrapper, holder, id, desc, flags); if (!ok || desc.object()) return ok; + // Check for indexed access on a window. + int32_t index = GetArrayIndexFromId(cx, id); + if (IsArrayIndex(index)) { + nsGlobalWindow* win = AsWindow(cx, wrapper); + // Note: As() unwraps outer windows to get to the inner window. + if (win) { + bool unused; + nsCOMPtr<nsIDOMWindow> subframe = win->IndexedGetter(index, unused); + if (subframe) { + nsGlobalWindow* global = static_cast<nsGlobalWindow*>(subframe.get()); + global->EnsureInnerWindow(); + JSObject* obj = global->FastGetGlobalJSObject(); + if (MOZ_UNLIKELY(!obj)) { + // It's gone? + return xpc::Throw(cx, NS_ERROR_FAILURE); + } + desc.value().setObject(*obj); + FillPropertyDescriptor(desc, wrapper, true); + return JS_WrapPropertyDescriptor(cx, desc); + } + } + } + RootedObject obj(cx, getTargetObject(wrapper)); if (!XrayResolveOwnProperty(cx, wrapper, obj, id, desc, flags)) return false; MOZ_ASSERT(!desc.object() || desc.object() == wrapper, "What did we resolve this on?"); return true; } @@ -1114,16 +1144,24 @@ DOMXrayTraits::resolveOwnProperty(JSCont bool DOMXrayTraits::defineProperty(JSContext *cx, HandleObject wrapper, HandleId id, MutableHandle<JSPropertyDescriptor> desc, Handle<JSPropertyDescriptor> existingDesc, bool *defined) { if (!existingDesc.object()) return true; + // Check for an indexed property on a Window. If that's happening, do + // nothing but claim we defined it so it won't get added as an expando. + int32_t index = GetArrayIndexFromId(cx, id); + if (IsArrayIndex(index) && IsWindow(cx, wrapper)) { + *defined = true; + return true; + } + JS::Rooted<JSObject*> obj(cx, getTargetObject(wrapper)); return XrayDefineProperty(cx, wrapper, obj, id, desc, defined); } bool DOMXrayTraits::enumerateNames(JSContext *cx, HandleObject wrapper, unsigned flags, AutoIdVector &props) { @@ -1465,30 +1503,28 @@ XrayWrapper<Base, Traits>::getPropertyDe // We need to handle named access on the Window somewhere other than // Traits::resolveOwnProperty, because per spec it happens on the Global // Scope Polluter and thus the resulting properties are non-|own|. However, // we're set up (above) to cache (on the holder) anything that comes out of // resolveNativeProperty, which we don't want for something dynamic like // named access. So we just handle it separately here. nsGlobalWindow *win = nullptr; if (!desc.object() && - (Traits::Type == XrayForWrappedNative) && JSID_IS_STRING(id) && - (win = static_cast<nsGlobalWindow*>(As<nsPIDOMWindow>(wrapper)))) + (win = AsWindow(cx, wrapper))) { nsDependentJSString name(id); nsCOMPtr<nsIDOMWindow> childDOMWin = win->GetChildWindow(name); if (childDOMWin) { nsGlobalWindow *cwin = static_cast<nsGlobalWindow*>(childDOMWin.get()); JSObject *childObj = cwin->FastGetGlobalJSObject(); if (MOZ_UNLIKELY(!childObj)) return xpc::Throw(cx, NS_ERROR_FAILURE); - mozilla::dom::FillPropertyDescriptor(desc, wrapper, - ObjectValue(*childObj), - /* readOnly = */ true); + FillPropertyDescriptor(desc, wrapper, ObjectValue(*childObj), + /* readOnly = */ true); return JS_WrapPropertyDescriptor(cx, desc); } } if (!desc.object() && id == nsXPConnect::GetRuntimeInstance()->GetStringID(XPCJSRuntime::IDX_TO_STRING)) {