diff --git a/js/src/xpconnect/src/XPCWrapper.h b/js/src/xpconnect/src/XPCWrapper.h index 756b88161d1f..8b077cb679a8 100644 --- a/js/src/xpconnect/src/XPCWrapper.h +++ b/js/src/xpconnect/src/XPCWrapper.h @@ -215,6 +215,15 @@ public: return JS_TRUE; } + static JSBool IsSecurityWrapper(JSObject *wrapper) + { + JSClass *clasp = STOBJ_GET_CLASS(wrapper); + return clasp == &sXPC_COW_JSClass.base || + clasp == &sXPC_SJOW_JSClass.base || + clasp == &sXPC_SOW_JSClass.base || + clasp == &sXPC_XOW_JSClass.base; + } + /** * Given an arbitrary object, Unwrap will return the wrapped object if the * passed-in object is a wrapper that Unwrap knows about *and* the diff --git a/js/src/xpconnect/src/xpcconvert.cpp b/js/src/xpconnect/src/xpcconvert.cpp index 40d247a47644..e1db5deefa34 100644 --- a/js/src/xpconnect/src/xpcconvert.cpp +++ b/js/src/xpconnect/src/xpcconvert.cpp @@ -149,24 +149,6 @@ XPCConvert::IsMethodReflectable(const XPTMethodDescriptor& info) /***************************************************************************/ -// static -JSBool -XPCConvert::GetISupportsFromJSObject(JSObject* obj, nsISupports** iface) -{ - JSClass* jsclass = STOBJ_GET_CLASS(obj); - NS_ASSERTION(jsclass, "obj has no class"); - if(jsclass && - (jsclass->flags & JSCLASS_HAS_PRIVATE) && - (jsclass->flags & JSCLASS_PRIVATE_IS_NSISUPPORTS)) - { - *iface = (nsISupports*) xpc_GetJSPrivate(obj); - return JS_TRUE; - } - return JS_FALSE; -} - -/***************************************************************************/ - static void FinalizeXPCOMUCString(JSContext *cx, JSString *str) { @@ -1459,32 +1441,39 @@ XPCConvert::JSObject2NativeInterface(XPCCallContext& ccx, // wrappedNative or other wise has 'nsISupportness'. // This allows wrapJSAggregatedToNative to work. + // If we're looking at a security wrapper, see now if we're allowed to + // pass it to C++. If we are, then fall through to the code below. If + // we aren't, throw an exception eagerly. + JSObject* inner = nsnull; + if(XPCWrapper::IsSecurityWrapper(src)) + { + inner = XPCWrapper::Unwrap(cx, src); + if(!inner) + { + if(pErr) + *pErr = NS_ERROR_XPC_SECURITY_MANAGER_VETO; + return JS_FALSE; + } + } + // Is this really a native xpcom object with a wrapper? XPCWrappedNative* wrappedNative = - XPCWrappedNative::GetWrappedNativeOfJSObject(cx, src); + XPCWrappedNative::GetWrappedNativeOfJSObject(cx, + inner + ? inner + : src); if(wrappedNative) { iface = wrappedNative->GetIdentityObject(); return NS_SUCCEEDED(iface->QueryInterface(*iid, dest)); } // else... - + // XXX E4X breaks the world. Don't try wrapping E4X objects! // This hack can be removed (or changed accordingly) when the // DOM <-> E4X bindings are complete, see bug 270553 if(JS_TypeOfValue(cx, OBJECT_TO_JSVAL(src)) == JSTYPE_XML) return JS_FALSE; - - // Does the JSObject have 'nsISupportness'? - // XXX hmm, I wonder if this matters anymore with no - // oldstyle DOM objects around. - if(GetISupportsFromJSObject(src, &iface)) - { - if(iface) - return NS_SUCCEEDED(iface->QueryInterface(*iid, dest)); - - return JS_FALSE; - } } // else... diff --git a/js/src/xpconnect/src/xpcprivate.h b/js/src/xpconnect/src/xpcprivate.h index 6636cee429f8..9c2fad0d3426 100644 --- a/js/src/xpconnect/src/xpcprivate.h +++ b/js/src/xpconnect/src/xpcprivate.h @@ -3037,7 +3037,6 @@ public: const nsID* iid, nsISupports* aOuter, nsresult* pErr); - static JSBool GetISupportsFromJSObject(JSObject* obj, nsISupports** iface); /** * Convert a native array into a jsval. diff --git a/js/src/xpconnect/src/xpcquickstubs.cpp b/js/src/xpconnect/src/xpcquickstubs.cpp index 710789c87bc5..ec4e6014ab87 100644 --- a/js/src/xpconnect/src/xpcquickstubs.cpp +++ b/js/src/xpconnect/src/xpcquickstubs.cpp @@ -839,6 +839,13 @@ xpc_qsUnwrapThisImpl(JSContext *cx, jsval *vp, XPCLazyCallContext *lccx) { + if(XPCWrapper::IsSecurityWrapper(obj)) + { + obj = XPCWrapper::Unwrap(cx, obj); + if(!obj) + return xpc_qsThrow(cx, NS_ERROR_XPC_SECURITY_MANAGER_VETO); + } + JSObject *cur = obj; XPCWrappedNativeTearOff *tearoff; XPCWrappedNative *wrapper = @@ -927,9 +934,17 @@ xpc_qsUnwrapArgImpl(JSContext *cx, return NS_OK; } + JSObject *inner = nsnull; + if(XPCWrapper::IsSecurityWrapper(src)) + { + inner = XPCWrapper::Unwrap(cx, src); + if(!inner) + return NS_ERROR_XPC_SECURITY_MANAGER_VETO; + } + // From XPCConvert::JSObject2NativeInterface XPCWrappedNative* wrappedNative = - XPCWrappedNative::GetWrappedNativeOfJSObject(cx, src); + XPCWrappedNative::GetWrappedNativeOfJSObject(cx, inner ? inner : src); nsISupports *iface; if(wrappedNative) { @@ -951,21 +966,6 @@ xpc_qsUnwrapArgImpl(JSContext *cx, return NS_ERROR_XPC_BAD_CONVERT_JS; } - // Does the JSObject have 'nsISupportness'? - // XXX hmm, I wonder if this matters anymore with no - // oldstyle DOM objects around. - if(XPCConvert::GetISupportsFromJSObject(src, &iface)) - { - if(!iface || NS_FAILED(iface->QueryInterface(iid, ppArg))) - { - *ppArgRef = nsnull; - return NS_ERROR_XPC_BAD_CONVERT_JS; - } - - *ppArgRef = static_cast(*ppArg); - return NS_OK; - } - // Create the ccx needed for quick stubs. XPCCallContext ccx(JS_CALLER, cx); if(!ccx.IsValid()) diff --git a/js/src/xpconnect/tests/mochitest/Makefile.in b/js/src/xpconnect/tests/mochitest/Makefile.in index 9e6d1e84d4cf..30804909601c 100644 --- a/js/src/xpconnect/tests/mochitest/Makefile.in +++ b/js/src/xpconnect/tests/mochitest/Makefile.in @@ -64,6 +64,7 @@ _TEST_FILES = bug500931_helper.html \ test_bug500691.html \ test_bug502959.html \ test_bug503926.html \ + test_bug505915.html \ test_bug517163.html \ $(NULL) diff --git a/js/src/xpconnect/tests/mochitest/test_bug505915.html b/js/src/xpconnect/tests/mochitest/test_bug505915.html new file mode 100644 index 000000000000..cfba3d001c16 --- /dev/null +++ b/js/src/xpconnect/tests/mochitest/test_bug505915.html @@ -0,0 +1,65 @@ + + + + + Test for Bug 505915 + + + + + +Mozilla Bug 505915 +

+ +
+
+
+ + + + +