JSBool xpc_JSObjectIsID(JSContext *cx, JSObject* obj) { NS_ASSERTION(cx && obj, "bad param"); // NOTE: this call does NOT addref XPCWrappedNative* wrapper = XPCWrappedNative::GetWrappedNativeOfJSObject(cx, obj); return wrapper && (wrapper->HasInterfaceNoQI(NS_GET_IID(nsIJSID)) || wrapper->HasInterfaceNoQI(NS_GET_IID(nsIJSIID)) || wrapper->HasInterfaceNoQI(NS_GET_IID(nsIJSCID))); }
bool xpc_JSObjectIsID(JSContext* cx, JSObject* obj) { MOZ_ASSERT(cx && obj, "bad param"); // NOTE: this call does NOT addref XPCWrappedNative* wrapper = nullptr; obj = js::CheckedUnwrap(obj); if (obj && IS_WN_REFLECTOR(obj)) wrapper = XPCWrappedNative::Get(obj); return wrapper && (wrapper->HasInterfaceNoQI(NS_GET_IID(nsIJSID)) || wrapper->HasInterfaceNoQI(NS_GET_IID(nsIJSIID)) || wrapper->HasInterfaceNoQI(NS_GET_IID(nsIJSCID))); }
XPCWrappedNative* XPCCallContext::UnwrapThisIfAllowed(HandleObject obj, HandleObject fun, unsigned argc) { // We should only get here for objects that aren't safe to unwrap. MOZ_ASSERT(!js::CheckedUnwrap(obj)); MOZ_ASSERT(js::IsObjectInContextCompartment(obj, mJSContext)); // We can't do anything here without a function. if (!fun) return nullptr; // Determine if we're allowed to unwrap the security wrapper to invoke the // method. // // We have the Interface and Member that this corresponds to, but // unfortunately our access checks are based on the object class name and // property name. So we cheat a little bit here - we verify that the object // does indeed implement the method's Interface, and then just check that we // can successfully access property with method's name from the object. // First, get the XPCWN out of the underlying object. We should have a wrapper // here, potentially an outer window proxy, and then an XPCWN. MOZ_ASSERT(js::IsWrapper(obj)); RootedObject unwrapped(mJSContext, js::UncheckedUnwrap(obj, /* stopAtOuter = */ false)); #ifdef DEBUG JS::Rooted<JSObject*> wrappedObj(mJSContext, js::Wrapper::wrappedObject(obj)); MOZ_ASSERT(unwrapped == JS_ObjectToInnerObject(mJSContext, wrappedObj)); #endif // Make sure we have an XPCWN, and grab it. if (!IS_WN_REFLECTOR(unwrapped)) return nullptr; XPCWrappedNative *wn = XPCWrappedNative::Get(unwrapped); // Next, get the call info off the function object. XPCNativeInterface *interface; XPCNativeMember *member; XPCNativeMember::GetCallInfo(fun, &interface, &member); // To be extra safe, make sure that the underlying native implements the // interface before unwrapping. Even if we didn't check this, we'd still // theoretically fail during tearoff lookup for mismatched methods. if (!wn->HasInterfaceNoQI(*interface->GetIID())) return nullptr; // See if the access is permitted. // // NB: This calculation of SET vs GET is a bit wonky, but that's what // XPC_WN_GetterSetter does. bool set = argc && argc != NO_ARGS && member->IsWritableAttribute(); js::Wrapper::Action act = set ? js::Wrapper::SET : js::Wrapper::GET; const js::Wrapper *handler = js::Wrapper::wrapperHandler(obj); bool ignored; JS::Rooted<jsid> id(mJSContext, member->GetName()); if (!handler->enter(mJSContext, obj, id, act, &ignored)) return nullptr; // Ok, this call is safe. return wn; }
// note: returned pointer is only valid while |obj| remains alive! const nsID* xpc_JSObjectToID(JSContext *cx, JSObject* obj) { if (!cx || !obj) return nsnull; // NOTE: this call does NOT addref XPCWrappedNative* wrapper = XPCWrappedNative::GetWrappedNativeOfJSObject(cx, obj); if (wrapper && (wrapper->HasInterfaceNoQI(NS_GET_IID(nsIJSID)) || wrapper->HasInterfaceNoQI(NS_GET_IID(nsIJSIID)) || wrapper->HasInterfaceNoQI(NS_GET_IID(nsIJSCID)))) { return ((nsIJSID*)wrapper->GetIdentityObject())->GetID(); } return nsnull; }
// note: returned pointer is only valid while |obj| remains alive! const nsID* xpc_JSObjectToID(JSContext* cx, JSObject* obj) { if (!cx || !obj) return nullptr; // NOTE: this call does NOT addref XPCWrappedNative* wrapper = nullptr; obj = js::CheckedUnwrap(obj); if (obj && IS_WN_REFLECTOR(obj)) wrapper = XPCWrappedNative::Get(obj); if (wrapper && (wrapper->HasInterfaceNoQI(NS_GET_IID(nsIJSID)) || wrapper->HasInterfaceNoQI(NS_GET_IID(nsIJSIID)) || wrapper->HasInterfaceNoQI(NS_GET_IID(nsIJSCID)))) { return ((nsIJSID*)wrapper->GetIdentityObject())->GetID(); } return nullptr; }