bool ChromeObjectWrapper::has(JSContext *cx, JS::Handle<JSObject*> wrapper, JS::Handle<jsid> id, bool *bp) { assertEnteredPolicy(cx, wrapper, id); // Try the lookup on the base wrapper if permitted. if (AllowedByBase(cx, wrapper, id, js::Wrapper::GET) && !ChromeObjectWrapperBase::has(cx, wrapper, id, bp)) { return false; } // If we found something or have no prototype, we're done. JSObject *wrapperProto; if (!JS_GetPrototype(cx, wrapper, &wrapperProto)) return false; if (*bp || !wrapperProto) return true; // Try the prototype if that failed. MOZ_ASSERT(js::IsObjectInContextCompartment(wrapper, cx)); JSPropertyDescriptor desc; if (!JS_GetPropertyDescriptorById(cx, wrapperProto, id, 0, &desc)) return false; *bp = !!desc.obj; return true; }
bool ChromeObjectWrapper::get(JSContext *cx, JS::Handle<JSObject*> wrapper, JS::Handle<JSObject*> receiver, JS::Handle<jsid> id, JS::MutableHandle<JS::Value> vp) { assertEnteredPolicy(cx, wrapper, id); vp.setUndefined(); JSPropertyDescriptor desc; // Only call through to the get trap on the underlying object if we're // allowed to see the property, and if what we'll find is not on a standard // prototype. if (AllowedByBase(cx, wrapper, id, js::Wrapper::GET) && !PropIsFromStandardPrototype(cx, wrapper, id)) { // Call the get trap. if (!ChromeObjectWrapperBase::get(cx, wrapper, receiver, id, vp)) return false; // If we found something, we're done. if (!vp.isUndefined()) return true; } // If we have no proto, we're done. JSObject *wrapperProto; if (!JS_GetPrototype(cx, wrapper, &wrapperProto)) return false; if (!wrapperProto) return true; // Try the prototype. MOZ_ASSERT(js::IsObjectInContextCompartment(wrapper, cx)); return js::GetGeneric(cx, wrapperProto, receiver, id, vp.address()); }
bool ChromeObjectWrapper::getPropertyDescriptor(JSContext *cx, JS::Handle<JSObject*> wrapper, JS::Handle<jsid> id, js::PropertyDescriptor *desc, unsigned flags) { assertEnteredPolicy(cx, wrapper, id); // First, try a lookup on the base wrapper if permitted. desc->obj = NULL; if (AllowedByBase(cx, wrapper, id, Wrapper::GET) && !ChromeObjectWrapperBase::getPropertyDescriptor(cx, wrapper, id, desc, flags)) { return false; } // If the property is something that can be found on a standard prototype, // prefer the one we'll get via the prototype chain in the content // compartment. if (desc->obj && PropIsFromStandardPrototype(cx, desc)) desc->obj = NULL; // If we found something or have no proto, we're done. JSObject *wrapperProto; if (!JS_GetPrototype(cx, wrapper, &wrapperProto)) return false; if (desc->obj || !wrapperProto) return true; // If not, try doing the lookup on the prototype. MOZ_ASSERT(js::IsObjectInContextCompartment(wrapper, cx)); return JS_GetPropertyDescriptorById(cx, wrapperProto, id, 0, desc); }
bool ChromeObjectWrapper::has(JSContext *cx, HandleObject wrapper, HandleId id, bool *bp) { assertEnteredPolicy(cx, wrapper, id); // Try the lookup on the base wrapper if permitted. if (AllowedByBase(cx, wrapper, id, js::Wrapper::GET) && !ChromeObjectWrapperBase::has(cx, wrapper, id, bp)) { return false; } // If we found something or have no prototype, we're done. RootedObject wrapperProto(cx); if (!JS_GetPrototype(cx, wrapper, wrapperProto.address())) return false; if (*bp || !wrapperProto) return true; // Try the prototype if that failed. MOZ_ASSERT(js::IsObjectInContextCompartment(wrapper, cx)); Rooted<JSPropertyDescriptor> desc(cx); if (!JS_GetPropertyDescriptorById(cx, wrapperProto, id, 0, desc.address())) return false; *bp = !!desc.object(); return true; }