// Find the subject and object principal. The argument // subjectPrincipal can be null if the caller doesn't care about the // subject principal, and secMgr can also be null if the caller // doesn't need the security manager. static nsresult FindPrincipals(JSContext *cx, JSObject *obj, nsIPrincipal **objectPrincipal, nsIPrincipal **subjectPrincipal, nsIScriptSecurityManager **secMgr) { XPCCallContext ccx(JS_CALLER, cx); if (!ccx.IsValid()) { return NS_ERROR_UNEXPECTED; } nsIScriptSecurityManager *ssm = XPCWrapper::GetSecurityManager(); if (subjectPrincipal) { NS_IF_ADDREF(*subjectPrincipal = ssm->GetCxSubjectPrincipal(cx)); } ssm->GetObjectPrincipal(cx, obj, objectPrincipal); if (secMgr) { NS_ADDREF(*secMgr = ssm); } return *objectPrincipal ? NS_OK : NS_ERROR_XPC_SECURITY_MANAGER_VETO; }
static JSBool XPC_XOW_Enumerate(JSContext *cx, JSObject *obj) { obj = GetWrapper(obj); JSObject *wrappedObj = GetWrappedObject(cx, obj); if (!wrappedObj) { // Nothing to enumerate. return JS_TRUE; } XPCCallContext ccx(JS_CALLER, cx); if (!ccx.IsValid()) { return ThrowException(NS_ERROR_FAILURE, cx); } nsresult rv = CanAccessWrapper(cx, wrappedObj, nsnull); if (NS_FAILED(rv)) { if (rv == NS_ERROR_DOM_PROP_ACCESS_DENIED) { // Can't enumerate on foreign objects. return ThrowException(rv, cx); } return JS_FALSE; } return XPCWrapper::Enumerate(cx, obj, wrappedObj); }
static JSBool XPC_XOW_Construct(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) { JSObject *realObj = GetWrapper(JSVAL_TO_OBJECT(argv[-2])); JSObject *wrappedObj = GetWrappedObject(cx, realObj); if (!wrappedObj) { // Nothing to construct. return JS_TRUE; } XPCCallContext ccx(JS_CALLER, cx); if (!ccx.IsValid()) { return ThrowException(NS_ERROR_FAILURE, cx); } nsresult rv = CanAccessWrapper(cx, wrappedObj, nsnull); if (NS_FAILED(rv)) { if (rv == NS_ERROR_DOM_PROP_ACCESS_DENIED) { // Can't construct. return ThrowException(rv, cx); } return JS_FALSE; } if (!JS_CallFunctionValue(cx, obj, OBJECT_TO_JSVAL(wrappedObj), argc, argv, rval)) { return JS_FALSE; } return XPC_XOW_RewrapIfNeeded(cx, wrappedObj, rval); }
static JSBool XPC_COW_Convert(JSContext *cx, JSObject *obj, JSType type, jsval *vp) { // Don't do any work to convert to object. if (type == JSTYPE_OBJECT) { *vp = OBJECT_TO_JSVAL(obj); return JS_TRUE; } JSObject *wrappedObj = GetWrappedObject(cx, obj); if (!wrappedObj) { // Converting the prototype to something. *vp = OBJECT_TO_JSVAL(obj); return JS_TRUE; } XPCCallContext ccx(JS_CALLER, cx); if (!ccx.IsValid()) { return ThrowException(NS_ERROR_FAILURE, cx); } if (!STOBJ_GET_CLASS(wrappedObj)->convert(cx, wrappedObj, type, vp)) { return JS_FALSE; } return XPC_COW_RewrapForContent(cx, obj, vp); }
static JSBool XPC_COW_NewResolve(JSContext *cx, JSObject *obj, jsval idval, uintN flags, JSObject **objp) { obj = GetWrapper(obj); JSObject *wrappedObj = GetWrappedObject(cx, obj); if (!wrappedObj) { // No wrappedObj means that this is probably the prototype. *objp = nsnull; return JS_TRUE; } XPCCallContext ccx(JS_CALLER, cx); if (!ccx.IsValid()) { return ThrowException(NS_ERROR_FAILURE, cx); } jsid id; JSBool canTouch; if (!JS_ValueToId(cx, idval, &id) || !CanTouchProperty(cx, obj, id, (flags & JSRESOLVE_ASSIGNING) != 0, &canTouch)) { return JS_FALSE; } if (!canTouch) { return ThrowException(NS_ERROR_XPC_SECURITY_MANAGER_VETO, cx); } return XPCWrapper::NewResolve(cx, obj, JS_TRUE, wrappedObj, id, flags, objp); }
static JSObject * XPC_COW_Iterator(JSContext *cx, JSObject *obj, JSBool keysonly) { JSObject *wrappedObj = GetWrappedObject(cx, obj); if (!wrappedObj) { ThrowException(NS_ERROR_INVALID_ARG, cx); return nsnull; } XPCCallContext ccx(JS_CALLER, cx); if (!ccx.IsValid()) { ThrowException(NS_ERROR_FAILURE, cx); return nsnull; } JSObject *wrapperIter = JS_NewObject(cx, &sXPC_COW_JSClass.base, nsnull, JS_GetGlobalForObject(cx, obj)); if (!wrapperIter) { return nsnull; } JSAutoTempValueRooter tvr(cx, OBJECT_TO_JSVAL(wrapperIter)); // Initialize our COW. jsval v = OBJECT_TO_JSVAL(wrappedObj); if (!JS_SetReservedSlot(cx, wrapperIter, XPCWrapper::sWrappedObjSlot, v) || !JS_SetReservedSlot(cx, wrapperIter, XPCWrapper::sFlagsSlot, JSVAL_ZERO)) { return nsnull; } return XPCWrapper::CreateIteratorObj(cx, wrapperIter, obj, wrappedObj, keysonly); }
static JSBool XPC_XOW_Call(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) { JSObject *wrappedObj = GetWrappedObject(cx, obj); if (!wrappedObj) { // Nothing to call. return JS_TRUE; } XPCCallContext ccx(JS_CALLER, cx); if (!ccx.IsValid()) { return ThrowException(NS_ERROR_FAILURE, cx); } nsresult rv = CanAccessWrapper(cx, wrappedObj, nsnull); if (NS_FAILED(rv)) { if (rv == NS_ERROR_DOM_PROP_ACCESS_DENIED) { // Can't call. return ThrowException(rv, cx); } return JS_FALSE; } JSObject *callee = JSVAL_TO_OBJECT(argv[-2]); NS_ASSERTION(GetWrappedObject(cx, callee), "How'd we get here?"); callee = GetWrappedObject(cx, callee); if (!JS_CallFunctionValue(cx, obj, OBJECT_TO_JSVAL(callee), argc, argv, rval)) { return JS_FALSE; } return XPC_XOW_RewrapIfNeeded(cx, callee, rval); }
/* PRBool resolve (in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj, in jsval id); */ NS_IMETHODIMP nsJSIID::NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext * cx, JSObject * obj, jsid id, PRUint32 flags, JSObject * *objp, PRBool *_retval) { XPCCallContext ccx(JS_CALLER, cx); AutoMarkingNativeInterfacePtr iface(ccx); const nsIID* iid; mInfo->GetIIDShared(&iid); iface = XPCNativeInterface::GetNewOrUsed(ccx, iid); if(!iface) return NS_OK; XPCNativeMember* member = iface->FindMember(id); if(member && member->IsConstant()) { jsval val; if(!member->GetConstantValue(ccx, iface, &val)) return NS_ERROR_OUT_OF_MEMORY; *objp = obj; *_retval = JS_DefinePropertyById(cx, obj, id, val, nsnull, nsnull, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT); } return NS_OK; }
/* PRBool enumerate (in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj); */ NS_IMETHODIMP nsJSIID::Enumerate(nsIXPConnectWrappedNative *wrapper, JSContext * cx, JSObject * obj, PRBool *_retval) { // In this case, let's just eagerly resolve... XPCCallContext ccx(JS_CALLER, cx); AutoMarkingNativeInterfacePtr iface(ccx); const nsIID* iid; mInfo->GetIIDShared(&iid); iface = XPCNativeInterface::GetNewOrUsed(ccx, iid); if(!iface) return NS_OK; PRUint16 count = iface->GetMemberCount(); for(PRUint16 i = 0; i < count; i++) { XPCNativeMember* member = iface->GetMemberAt(i); if(member && member->IsConstant() && !xpc_ForcePropertyResolve(cx, obj, member->GetName())) { return NS_ERROR_UNEXPECTED; } } return NS_OK; }
static JSBool XPC_XOW_DelProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp) { JSObject *wrappedObj = GetWrappedObject(cx, obj); if (!wrappedObj) { return ThrowException(NS_ERROR_ILLEGAL_VALUE, cx); } XPCCallContext ccx(JS_CALLER, cx); if (!ccx.IsValid()) { return ThrowException(NS_ERROR_FAILURE, cx); } nsresult rv = CanAccessWrapper(cx, wrappedObj, nsnull); if (NS_FAILED(rv)) { if (rv == NS_ERROR_DOM_PROP_ACCESS_DENIED) { // Can't delete properties on foreign objects. return ThrowException(rv, cx); } return JS_FALSE; } // Same origin, pass this request along. return XPCWrapper::DelProperty(cx, wrappedObj, id, vp); }
static JSBool XPC_XOW_FunctionWrapper(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) { JSObject *wrappedObj, *outerObj = obj; // Allow 'this' to be either an XOW, in which case we unwrap it. // We disallow invalid XOWs that have no wrapped object. Otherwise, // if it isn't an XOW, then pass it through as-is. wrappedObj = GetWrapper(obj); if (wrappedObj) { wrappedObj = GetWrappedObject(cx, wrappedObj); if (!wrappedObj) { return ThrowException(NS_ERROR_ILLEGAL_VALUE, cx); } } else { wrappedObj = obj; } JSObject *funObj = JSVAL_TO_OBJECT(argv[-2]); jsval funToCall; if (!JS_GetReservedSlot(cx, funObj, XPCWrapper::eWrappedFunctionSlot, &funToCall)) { return JS_FALSE; } JSFunction *fun = JS_ValueToFunction(cx, funToCall); if (!fun) { return ThrowException(NS_ERROR_ILLEGAL_VALUE, cx); } XPCCallContext ccx(JS_CALLER, cx); if (!ccx.IsValid()) { return ThrowException(NS_ERROR_FAILURE, cx); } nsresult rv = CanAccessWrapper(cx, JSVAL_TO_OBJECT(funToCall), nsnull); if (NS_FAILED(rv) && rv != NS_ERROR_DOM_PROP_ACCESS_DENIED) { return ThrowException(rv, cx); } #ifdef DEBUG JSNative native = JS_GetFunctionNative(cx, fun); NS_ASSERTION(native, "How'd we get here with a scripted function?"); #endif if (!JS_CallFunctionValue(cx, wrappedObj, funToCall, argc, argv, rval)) { return JS_FALSE; } if (NS_SUCCEEDED(rv)) { return WrapSameOriginProp(cx, outerObj, rval); } return XPC_XOW_RewrapIfNeeded(cx, obj, rval); }
/* readonly attribute nsISimpleEnumerator enumerator; */ NS_IMETHODIMP nsXPCWrappedJS::GetEnumerator(nsISimpleEnumerator * *aEnumerate) { XPCCallContext ccx(NATIVE_CALLER); if (!ccx.IsValid()) return NS_ERROR_UNEXPECTED; return nsXPCWrappedJSClass::BuildPropertyEnumerator(ccx, GetJSObject(), aEnumerate); }
/* nsIVariant getProperty (in AString name); */ NS_IMETHODIMP nsXPCWrappedJS::GetProperty(const nsAString & name, nsIVariant **_retval) { XPCCallContext ccx(NATIVE_CALLER); if (!ccx.IsValid()) return NS_ERROR_UNEXPECTED; return nsXPCWrappedJSClass:: GetNamedPropertyAsVariant(ccx, GetJSObject(), name, _retval); }
static JSBool XPC_COW_GetOrSetProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp, JSBool isSet) { obj = GetWrapper(obj); if (!obj) { return ThrowException(NS_ERROR_ILLEGAL_VALUE, cx); } XPCCallContext ccx(JS_CALLER, cx); if (!ccx.IsValid()) { return ThrowException(NS_ERROR_FAILURE, cx); } AUTO_MARK_JSVAL(ccx, vp); JSObject *wrappedObj = GetWrappedObject(cx, obj); if (!wrappedObj) { return ThrowException(NS_ERROR_ILLEGAL_VALUE, cx); } jsid interned_id; if (!JS_ValueToId(cx, id, &interned_id)) { return JS_FALSE; } if (interned_id == GetRTIdByIndex(cx, XPCJSRuntime::IDX_PROTO) || interned_id == GetRTIdByIndex(cx, XPCJSRuntime::IDX_PARENT) || interned_id == GetRTIdByIndex(cx, XPCJSRuntime::IDX_EXPOSEDPROPS)) { // No getting or setting __proto__ or __parent__ on my object. return ThrowException(NS_ERROR_INVALID_ARG, cx); // XXX better error message } JSBool canTouch; if (!CanTouchProperty(cx, obj, interned_id, isSet, &canTouch)) { return JS_FALSE; } if (!canTouch) { return ThrowException(NS_ERROR_XPC_SECURITY_MANAGER_VETO, cx); } if (!XPC_COW_RewrapForChrome(cx, obj, vp)) { return JS_FALSE; } JSBool ok = isSet ? JS_SetPropertyById(cx, wrappedObj, interned_id, vp) : JS_GetPropertyById(cx, wrappedObj, interned_id, vp); if (!ok) { return JS_FALSE; } return XPC_COW_RewrapForContent(cx, obj, vp); }
nsresult xpcJSWeakReference::Init() { nsresult rv; nsXPConnect* xpc = nsXPConnect::GetXPConnect(); if (!xpc) return NS_ERROR_UNEXPECTED; nsAXPCNativeCallContext *cc = nsnull; rv = xpc->GetCurrentNativeCallContext(&cc); NS_ENSURE_SUCCESS(rv, rv); JSContext *cx = nsnull; rv = cc->GetJSContext(&cx); NS_ENSURE_SUCCESS(rv, rv); PRUint32 argc = 0; rv = cc->GetArgc(&argc); NS_ENSURE_SUCCESS(rv, rv); if (argc != 1) return NS_ERROR_FAILURE; jsval *argv = nsnull; rv = cc->GetArgvPtr(&argv); NS_ENSURE_SUCCESS(rv, rv); JSAutoRequest ar(cx); if (JSVAL_IS_NULL(argv[0])) return NS_ERROR_FAILURE; JSObject *obj; if (!JS_ValueToObject(cx, argv[0], &obj)) return NS_ERROR_FAILURE; XPCCallContext ccx(NATIVE_CALLER, cx); nsRefPtr<nsXPCWrappedJS> wrapped; rv = nsXPCWrappedJS::GetNewOrUsed(ccx, obj, NS_GET_IID(nsISupports), nsnull, getter_AddRefs(wrapped)); if (!wrapped) { NS_ERROR("can't get nsISupportsWeakReference wrapper for obj"); return rv; } return static_cast<nsISupportsWeakReference*>(wrapped)-> GetWeakReference(getter_AddRefs(mWrappedJSObject)); }
static JSObject * XPC_XOW_Iterator(JSContext *cx, JSObject *obj, JSBool keysonly) { JSObject *wrappedObj = GetWrappedObject(cx, obj); if (!wrappedObj) { ThrowException(NS_ERROR_INVALID_ARG, cx); return nsnull; } XPCCallContext ccx(JS_CALLER, cx); if (!ccx.IsValid()) { ThrowException(NS_ERROR_FAILURE, cx); return nsnull; } nsresult rv = CanAccessWrapper(cx, wrappedObj, nsnull); if (NS_FAILED(rv)) { if (rv == NS_ERROR_DOM_PROP_ACCESS_DENIED) { // Can't create iterators for foreign objects. ThrowException(rv, cx); return nsnull; } ThrowException(NS_ERROR_FAILURE, cx); return nsnull; } JSObject *wrapperIter = JS_NewObject(cx, &sXPC_XOW_JSClass.base, nsnull, JS_GetGlobalForObject(cx, obj)); if (!wrapperIter) { return nsnull; } JSAutoTempValueRooter tvr(cx, OBJECT_TO_JSVAL(wrapperIter)); // Initialize our XOW. jsval v = OBJECT_TO_JSVAL(wrappedObj); if (!JS_SetReservedSlot(cx, wrapperIter, XPCWrapper::sWrappedObjSlot, v) || !JS_SetReservedSlot(cx, wrapperIter, XPCWrapper::sFlagsSlot, JSVAL_ZERO) || !JS_SetReservedSlot(cx, wrapperIter, XPC_XOW_ScopeSlot, PRIVATE_TO_JSVAL(nsnull))) { return nsnull; } return XPCWrapper::CreateIteratorObj(cx, wrapperIter, obj, wrappedObj, keysonly); }
static JSBool XPC_COW_DelProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp) { JSObject *wrappedObj = GetWrappedObject(cx, obj); if (!wrappedObj) { return ThrowException(NS_ERROR_ILLEGAL_VALUE, cx); } XPCCallContext ccx(JS_CALLER, cx); if (!ccx.IsValid()) { return ThrowException(NS_ERROR_FAILURE, cx); } // Deleting a property is safe. return XPCWrapper::DelProperty(cx, wrappedObj, id, vp); }
XPCDispTypeInfo * XPCDispatchTearOff::GetCOMTypeInfo() { // If one was already created return it if(mCOMTypeInfo) return mCOMTypeInfo; // Build a new one, save the pointer and return it XPCCallContext ccx(NATIVE_CALLER); if(!ccx.IsValid()) return nsnull; JSObject* obj = GetJSObject(); if(!obj) return nsnull; mCOMTypeInfo = XPCDispTypeInfo::New(ccx, obj); NS_IF_ADDREF(mCOMTypeInfo); return mCOMTypeInfo; }
/* nsIVariant getProperty (in AString name); */ NS_IMETHODIMP nsXPCWrappedJS::GetProperty(const nsAString & name, nsIVariant **_retval) { XPCCallContext ccx(NATIVE_CALLER); if (!ccx.IsValid()) return NS_ERROR_UNEXPECTED; nsStringBuffer* buf; jsval jsstr = XPCStringConvert::ReadableToJSVal(ccx, name, &buf); if (JSVAL_IS_NULL(jsstr)) return NS_ERROR_OUT_OF_MEMORY; if (buf) buf->AddRef(); return nsXPCWrappedJSClass:: GetNamedPropertyAsVariant(ccx, GetJSObject(), jsstr, _retval); }
static JSBool XPC_XOW_toString(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) { obj = GetWrapper(obj); if (!obj) { return ThrowException(NS_ERROR_UNEXPECTED, cx); } JSObject *wrappedObj = GetWrappedObject(cx, obj); if (!wrappedObj) { // Someone's calling toString on our prototype. NS_NAMED_LITERAL_CSTRING(protoString, "[object XPCCrossOriginWrapper]"); JSString *str = JS_NewStringCopyN(cx, protoString.get(), protoString.Length()); if (!str) { return JS_FALSE; } *rval = STRING_TO_JSVAL(str); return JS_TRUE; } XPCCallContext ccx(JS_CALLER, cx); if (!ccx.IsValid()) { return ThrowException(NS_ERROR_FAILURE, cx); } nsresult rv = CanAccessWrapper(cx, wrappedObj, nsnull); if (rv == NS_ERROR_DOM_PROP_ACCESS_DENIED) { nsIScriptSecurityManager *ssm = XPCWrapper::GetSecurityManager(); if (!ssm) { return ThrowException(NS_ERROR_NOT_INITIALIZED, cx); } rv = ssm->CheckPropertyAccess(cx, wrappedObj, STOBJ_GET_CLASS(wrappedObj)->name, GetRTStringByIndex(cx, XPCJSRuntime::IDX_TO_STRING), nsIXPCSecurityManager::ACCESS_GET_PROPERTY); } if (NS_FAILED(rv)) { return JS_FALSE; } XPCWrappedNative *wn = XPCWrappedNative::GetWrappedNativeOfJSObject(cx, wrappedObj); return XPCWrapper::NativeToString(cx, wn, argc, argv, rval, JS_FALSE); }
static JSBool XPC_COW_Enumerate(JSContext *cx, JSObject *obj) { obj = GetWrapper(obj); JSObject *wrappedObj = GetWrappedObject(cx, obj); if (!wrappedObj) { // Nothing to enumerate. return JS_TRUE; } XPCCallContext ccx(JS_CALLER, cx); if (!ccx.IsValid()) { return ThrowException(NS_ERROR_FAILURE, cx); } return XPCWrapper::Enumerate(cx, obj, wrappedObj); }
static JSBool XPC_XOW_Convert(JSContext *cx, JSObject *obj, JSType type, jsval *vp) { // Don't do any work to convert to object. if (type == JSTYPE_OBJECT) { *vp = OBJECT_TO_JSVAL(obj); return JS_TRUE; } JSObject *wrappedObj = GetWrappedObject(cx, obj); if (!wrappedObj) { // Converting the prototype to something. if (type == JSTYPE_STRING || type == JSTYPE_VOID) { return XPC_XOW_toString(cx, obj, 0, nsnull, vp); } *vp = OBJECT_TO_JSVAL(obj); return JS_TRUE; } XPCCallContext ccx(JS_CALLER, cx); if (!ccx.IsValid()) { return ThrowException(NS_ERROR_FAILURE, cx); } // Note: JSTYPE_VOID and JSTYPE_STRING are equivalent. nsresult rv = CanAccessWrapper(cx, wrappedObj, nsnull); if (NS_FAILED(rv) && (rv != NS_ERROR_DOM_PROP_ACCESS_DENIED || (type != JSTYPE_STRING && type != JSTYPE_VOID))) { // Ensure that we report some kind of error. if (rv == NS_ERROR_DOM_PROP_ACCESS_DENIED) { ThrowException(rv, cx); } return JS_FALSE; } if (!STOBJ_GET_CLASS(wrappedObj)->convert(cx, wrappedObj, type, vp)) { return JS_FALSE; } return NS_SUCCEEDED(rv) ? WrapSameOriginProp(cx, obj, vp) : XPC_XOW_RewrapIfNeeded(cx, obj, vp); }
/* PRBool hasInstance (in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj, in JSVal val, out PRBool bp); */ NS_IMETHODIMP nsJSIID::HasInstance(nsIXPConnectWrappedNative *wrapper, JSContext * cx, JSObject * obj, jsval val, PRBool *bp, PRBool *_retval) { *bp = JS_FALSE; nsresult rv = NS_OK; if(!JSVAL_IS_PRIMITIVE(val)) { // we have a JSObject JSObject* obj = JSVAL_TO_OBJECT(val); NS_ASSERTION(obj, "when is an object not an object?"); // is this really a native xpcom object with a wrapper? XPCWrappedNative* other_wrapper = XPCWrappedNative::GetWrappedNativeOfJSObject(cx, obj); if(!other_wrapper) return NS_OK; const nsIID* iid; mInfo->GetIIDShared(&iid); // We'll trust the interface set of the wrapper if this is known // to be an interface that the objects *expects* to be able to // handle. if(other_wrapper->HasInterfaceNoQI(*iid)) { *bp = JS_TRUE; return NS_OK; } // Otherwise, we'll end up Querying the native object to be sure. XPCCallContext ccx(JS_CALLER, cx); AutoMarkingNativeInterfacePtr iface(ccx); iface = XPCNativeInterface::GetNewOrUsed(ccx, iid); if(iface && other_wrapper->FindTearOff(ccx, iface)) *bp = JS_TRUE; } return rv; }
/* PRBool construct (in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj, in PRUint32 argc, in JSValPtr argv, in JSValPtr vp); */ NS_IMETHODIMP nsJSCID::Construct(nsIXPConnectWrappedNative *wrapper, JSContext * cx, JSObject * obj, PRUint32 argc, jsval * argv, jsval * vp, PRBool *_retval) { XPCJSRuntime* rt = nsXPConnect::GetRuntimeInstance(); if(!rt) return NS_ERROR_FAILURE; // 'push' a call context and call on it XPCCallContext ccx(JS_CALLER, cx, obj, nsnull, rt->GetStringID(XPCJSRuntime::IDX_CREATE_INSTANCE), argc, argv, vp); *_retval = XPCWrappedNative::CallMethod(ccx); return NS_OK; }
ActiveXSupports(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) { XPCCallContext ccx(JS_CALLER, cx, JS_GetGlobalObject(cx)); // Check if IDispatch is enabled, fail if not if(!nsXPConnect::IsIDispatchEnabled()) { XPCThrower::Throw(NS_ERROR_XPC_IDISPATCH_NOT_ENABLED, ccx); return JS_FALSE; } XPCJSRuntime *rt = ccx.GetRuntime(); if(!rt) { XPCThrower::Throw(NS_ERROR_UNEXPECTED, ccx); return JS_FALSE; } // Make sure we were called with one string parameter if(argc != 1 || (argc == 1 && !JSVAL_IS_STRING(argv[0]))) { XPCThrower::Throw(NS_ERROR_XPC_COM_INVALID_CLASS_ID, ccx); return JS_FALSE; } PRUint32 len; jschar * className = xpc_JSString2String(ccx, argv[0], &len); CComBSTR bstrClassName(len, reinterpret_cast<const WCHAR *>(className)); if(!className) { XPCThrower::Throw(NS_ERROR_XPC_COM_INVALID_CLASS_ID, ccx); return JS_FALSE; } CLSID classID = CLSID_NULL; HRESULT hr = CLSIDFromString(bstrClassName, &classID); if(FAILED(hr) || ::IsEqualCLSID(classID, CLSID_NULL)) { XPCThrower::Throw(NS_ERROR_XPC_COM_INVALID_CLASS_ID, ccx); return JS_FALSE; } // Instantiate the desired COM object HRESULT rv = XPCDispObject::SecurityCheck(ccx, classID); *rval = BOOLEAN_TO_JSVAL(SUCCEEDED(rv)); return JS_TRUE; }
static JSBool XPC_XOW_AddProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp) { // All AddProperty needs to do is pass on addProperty requests to // same-origin objects, and throw for all else. obj = GetWrapper(obj); jsval resolving; if (!JS_GetReservedSlot(cx, obj, XPCWrapper::sFlagsSlot, &resolving)) { return JS_FALSE; } if (HAS_FLAGS(resolving, FLAG_RESOLVING)) { // Allow us to define a property on ourselves. return JS_TRUE; } JSObject *wrappedObj = GetWrappedObject(cx, obj); if (!wrappedObj) { return ThrowException(NS_ERROR_ILLEGAL_VALUE, cx); } XPCCallContext ccx(JS_CALLER, cx); if (!ccx.IsValid()) { return ThrowException(NS_ERROR_FAILURE, cx); } JSBool privilegeEnabled = JS_FALSE; nsresult rv = CanAccessWrapper(cx, wrappedObj, &privilegeEnabled); if (NS_FAILED(rv)) { if (rv == NS_ERROR_DOM_PROP_ACCESS_DENIED) { // Can't override properties on foreign objects. return ThrowException(rv, cx); } return JS_FALSE; } // Same origin, pass this request along. return XPCWrapper::AddProperty(cx, obj, JS_TRUE, wrappedObj, id, vp); }
/** * Callback for functions * This callback is called by JS when a function on a JSObject proxying * for an IDispatch instance * @param cx A pointer to a JS context * @param obj JS object that the parameterized property is on * @param argc Number of arguments in this call * @param argv The parameters passed in if any * @param vp The return value * @return Returns JS_TRUE if the operation succeeded */ JSBool JS_DLL_CALLBACK XPC_IDispatch_CallMethod(JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* vp) { NS_ASSERTION(JS_TypeOfValue(cx, argv[-2]) == JSTYPE_FUNCTION, "bad function"); JSObject* funobj = JSVAL_TO_OBJECT(argv[-2]); XPCCallContext ccx(JS_CALLER, cx, obj, funobj, 0, argc, argv, vp); XPCWrappedNative* wrapper = ccx.GetWrapper(); THROW_AND_RETURN_IF_BAD_WRAPPER(cx, wrapper); ccx.SetArgsAndResultPtr(argc, argv, vp); XPCDispInterface::Member* member; XPCNativeInterface* iface; #ifdef DEBUG PRBool ok = #endif GetMember(ccx, funobj, iface, member); NS_ASSERTION(ok, "GetMember faild in XPC_IDispatch_CallMethod"); ccx.SetIDispatchInfo(iface, member); return XPCDispObject::Invoke(ccx, XPCDispObject::CALL_METHOD); }
static JSBool XPC_XOW_HasInstance(JSContext *cx, JSObject *obj, jsval v, JSBool *bp) { JSObject *iface = GetWrappedObject(cx, obj); XPCCallContext ccx(JS_CALLER, cx); if (!ccx.IsValid()) { return ThrowException(NS_ERROR_FAILURE, cx); } nsresult rv = CanAccessWrapper(cx, iface, nsnull); if (NS_FAILED(rv)) { if (rv == NS_ERROR_DOM_PROP_ACCESS_DENIED) { // Don't do this test across origins. return ThrowException(rv, cx); } return JS_FALSE; } JSClass *clasp = STOBJ_GET_CLASS(iface); *bp = JS_FALSE; if (!clasp->hasInstance) { return JS_TRUE; } // Prematurely unwrap the left hand side. if (!JSVAL_IS_PRIMITIVE(v)) { JSObject *test = JSVAL_TO_OBJECT(v); // GetWrappedObject does an instanceof check. test = GetWrappedObject(cx, test); if (test) { v = OBJECT_TO_JSVAL(test); } } return clasp->hasInstance(cx, iface, v, bp); }
nsresult xpcJSWeakReference::Init(JSContext* cx, const JS::Value& object) { if (!object.isObject()) return NS_OK; JS::RootedObject obj(cx, &object.toObject()); XPCCallContext ccx(NATIVE_CALLER, cx); // See if the object is a wrapped native that supports weak references. nsISupports* supports = nsXPConnect::XPConnect()->GetNativeOfWrapper(cx, obj); nsCOMPtr<nsISupportsWeakReference> supportsWeakRef = do_QueryInterface(supports); if (supportsWeakRef) { supportsWeakRef->GetWeakReference(getter_AddRefs(mReferent)); if (mReferent) { return NS_OK; } } // If it's not a wrapped native, or it is a wrapped native that does not // support weak references, fall back to getting a weak ref to the object. // See if object is a wrapped JSObject. nsRefPtr<nsXPCWrappedJS> wrapped; nsresult rv = nsXPCWrappedJS::GetNewOrUsed(ccx, obj, NS_GET_IID(nsISupports), nullptr, getter_AddRefs(wrapped)); if (!wrapped) { NS_ERROR("can't get nsISupportsWeakReference wrapper for obj"); return rv; } return wrapped->GetWeakReference(getter_AddRefs(mReferent)); }
nsresult xpcJSWeakReference::Init(JSContext* cx, const JS::Value& object) { JSAutoRequest ar(cx); if (!object.isObject()) return NS_ERROR_FAILURE; JSObject& obj = object.toObject(); XPCCallContext ccx(NATIVE_CALLER, cx); nsRefPtr<nsXPCWrappedJS> wrapped; nsresult rv = nsXPCWrappedJS::GetNewOrUsed(ccx, &obj, NS_GET_IID(nsISupports), nsnull, getter_AddRefs(wrapped)); if (!wrapped) { NS_ERROR("can't get nsISupportsWeakReference wrapper for obj"); return rv; } return wrapped->GetWeakReference(getter_AddRefs(mWrappedJSObject)); }