bool CrossOriginXrayWrapper::getPropertyDescriptor(JSContext* cx, JS::Handle<JSObject*> wrapper, JS::Handle<jsid> id, JS::MutableHandle<JSPropertyDescriptor> desc) const { if (!SecurityXrayDOM::getPropertyDescriptor(cx, wrapper, id, desc)) return false; if (desc.object()) { // All properties on cross-origin DOM objects are |own|. desc.object().set(wrapper); // All properties on cross-origin DOM objects are non-enumerable and // "configurable". Any value attributes are read-only. desc.attributesRef() &= ~JSPROP_ENUMERATE; desc.attributesRef() &= ~JSPROP_PERMANENT; if (!desc.getter() && !desc.setter()) desc.attributesRef() |= JSPROP_READONLY; } return true; }
static bool ResolveWindowNamedProperty(JSContext* aCx, JS::Handle<JSObject*> aWrapper, JS::Handle<JSObject*> aObj, JS::Handle<jsid> aId, JS::MutableHandle<JS::PropertyDescriptor> aDesc) { { JSAutoCompartment ac(aCx, aObj); if (!js::GetProxyHandler(aObj)->getOwnPropertyDescriptor(aCx, aObj, aId, aDesc)) { return false; } } if (aDesc.object()) { aDesc.object().set(aWrapper); return JS_WrapPropertyDescriptor(aCx, aDesc); } return true; }
bool WindowNamedPropertiesHandler::getOwnPropDescriptor(JSContext* aCx, JS::Handle<JSObject*> aProxy, JS::Handle<jsid> aId, bool /* unused */, JS::MutableHandle<JSPropertyDescriptor> aDesc) const { if (!JSID_IS_STRING(aId)) { // Nothing to do if we're resolving a non-string property. return true; } JS::Rooted<JSObject*> global(aCx, JS_GetGlobalForObject(aCx, aProxy)); if (HasPropertyOnPrototype(aCx, aProxy, aId)) { return true; } nsAutoJSString str; if (!str.init(aCx, JSID_TO_STRING(aId))) { return false; } // Grab the DOM window. nsGlobalWindow* win = GetWindowFromGlobal(global); if (win->Length() > 0) { nsCOMPtr<nsIDOMWindow> childWin = win->GetChildWindow(str); if (childWin && ShouldExposeChildWindow(str, childWin)) { // We found a subframe of the right name. Shadowing via |var foo| in // global scope is still allowed, since |var| only looks up |own| // properties. But unqualified shadowing will fail, per-spec. JS::Rooted<JS::Value> v(aCx); if (!WrapObject(aCx, childWin, &v)) { return false; } aDesc.object().set(aProxy); aDesc.value().set(v); aDesc.setAttributes(JSPROP_ENUMERATE); return true; } } // The rest of this function is for HTML documents only. nsCOMPtr<nsIHTMLDocument> htmlDoc = do_QueryInterface(win->GetExtantDoc()); if (!htmlDoc) { return true; } nsHTMLDocument* document = static_cast<nsHTMLDocument*>(htmlDoc.get()); Element* element = document->GetElementById(str); if (element) { JS::Rooted<JS::Value> v(aCx); if (!WrapObject(aCx, element, &v)) { return false; } aDesc.object().set(aProxy); aDesc.value().set(v); aDesc.setAttributes(JSPROP_ENUMERATE); return true; } nsWrapperCache* cache; nsISupports* result = document->ResolveName(str, &cache); if (!result) { return true; } JS::Rooted<JS::Value> v(aCx); if (!WrapObject(aCx, result, cache, nullptr, &v)) { return false; } aDesc.object().set(aProxy); aDesc.value().set(v); aDesc.setAttributes(JSPROP_ENUMERATE); return true; }