mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-29 07:42:04 +00:00
r=mccabe
Primarily fixes to properly handle nsIXPCSecurityManager vetos of xpconnect activities. - The code was not propagating security manager vetos of native wrapping up through xpconnect internals. So, xpconnect was erroneously masking the security exception with its own 'failed to convert param' exception. This effects the signatures of nsXPCWrappedNative::GetNewOrUsedWrapper and nsXPCWrappedJSClass::GetNewOrUsedClass. - This propagation also helps with the problem that sometimes interfaces are not set as [scriptable] and we did not make that clear as the source of xpconnect's failure to convert a param in calling a method. Now this specific class of exceptions is indicated in the JS exception object when this happens. - Added an explicit call to js_ForceGC on shutdown of xpcshell to aid in avoiding 'false positives' in leak detection - Return JS_FALSE rather than JS_TRUE when an exception is thrown in xpcjsid to make the jsengine notices the exception. - Move #includes that others added in xpcmodule.cpp to xpcprivate.h in order to maintain the include conventions of this module. - Avoid throwing an exception if it represents a security manager veto and the security manager set an exception already. - Replace uses of nsCOMTypeInfo<> added by scc with NS_GET_IID macros. - Fixed a methodname misspelling because reviewers care about stuff like that :)
This commit is contained in:
parent
8d8ce920cb
commit
2353651fe4
@ -110,6 +110,10 @@
|
||||
#define NS_ERROR_XPC_NOT_ENOUGH_ELEMENTS_IN_ARRAY GENERATE_XPC_FAILURE(36)
|
||||
#define NS_ERROR_XPC_CANT_GET_ARRAY_INFO GENERATE_XPC_FAILURE(37)
|
||||
#define NS_ERROR_XPC_NOT_ENOUGH_CHARS_IN_STRING GENERATE_XPC_FAILURE(38)
|
||||
#define NS_ERROR_XPC_SECURITY_MANAGER_VETO GENERATE_XPC_FAILURE(39)
|
||||
#define NS_ERROR_XPC_INTERFACE_NOT_SCRIPTABLE GENERATE_XPC_FAILURE(40)
|
||||
#define NS_ERROR_XPC_INTERFACE_NOT_FROM_NSISUPPORTS GENERATE_XPC_FAILURE(41)
|
||||
|
||||
|
||||
// any new errors here should have an associated entry added in xpc.msg
|
||||
|
||||
|
@ -663,6 +663,7 @@ main(int argc, char **argv)
|
||||
|
||||
xpc->AbandonJSContext(jscontext);
|
||||
NS_RELEASE(xpc);
|
||||
js_ForceGC(jscontext);
|
||||
JS_DestroyContext(jscontext);
|
||||
if (!rtsvc) {
|
||||
/* no runtime service, so we have to handle shutdown */
|
||||
|
@ -253,7 +253,7 @@ nsXPConnect::GetJSThrower(nsXPConnect* xpc /*= nsnull */)
|
||||
|
||||
// static
|
||||
JSBool
|
||||
nsXPConnect::IsISupportsDescendent(nsIInterfaceInfo* info)
|
||||
nsXPConnect::IsISupportsDescendant(nsIInterfaceInfo* info)
|
||||
{
|
||||
if(!info)
|
||||
return JS_FALSE;
|
||||
@ -356,7 +356,8 @@ nsXPConnect::InitJSContextWithNewWrappedGlobal(JSContext* aJSContext,
|
||||
if(!mContextMap->Find(aJSContext) &&
|
||||
nsnull != (xpcc = NewContext(aJSContext, nsnull, JS_FALSE)))
|
||||
{
|
||||
wrapper = nsXPCWrappedNative::GetNewOrUsedWrapper(xpcc, aCOMObj, aIID);
|
||||
wrapper = nsXPCWrappedNative::GetNewOrUsedWrapper(xpcc, aCOMObj,
|
||||
aIID, nsnull);
|
||||
if(wrapper)
|
||||
{
|
||||
if(JS_InitStandardClasses(aJSContext, wrapper->GetJSObject()) &&
|
||||
@ -478,7 +479,8 @@ nsXPConnect::WrapNative(JSContext* aJSContext,
|
||||
if(xpcc)
|
||||
{
|
||||
nsXPCWrappedNative* wrapper =
|
||||
nsXPCWrappedNative::GetNewOrUsedWrapper(xpcc, aCOMObj, aIID);
|
||||
nsXPCWrappedNative::GetNewOrUsedWrapper(xpcc, aCOMObj,
|
||||
aIID, nsnull);
|
||||
if(wrapper)
|
||||
{
|
||||
*aWrapper = wrapper;
|
||||
|
@ -75,6 +75,9 @@ XPC_MSG_DEF(NS_ERROR_XPC_CANT_CONVERT_OBJECT_TO_ARRAY , "Can not convert JavaS
|
||||
XPC_MSG_DEF(NS_ERROR_XPC_NOT_ENOUGH_ELEMENTS_IN_ARRAY , "JavaScript Array does not have as many elements as indicated by size argument")
|
||||
XPC_MSG_DEF(NS_ERROR_XPC_CANT_GET_ARRAY_INFO , "Can not find array information")
|
||||
XPC_MSG_DEF(NS_ERROR_XPC_NOT_ENOUGH_CHARS_IN_STRING , "JavaScript String does not have as many characters as indicated by size argument")
|
||||
XPC_MSG_DEF(NS_ERROR_XPC_SECURITY_MANAGER_VETO , "Security Manager vetoed action")
|
||||
XPC_MSG_DEF(NS_ERROR_XPC_INTERFACE_NOT_SCRIPTABLE , "Failed to build a wrapper because the interface that was not declared [scriptable]")
|
||||
XPC_MSG_DEF(NS_ERROR_XPC_INTERFACE_NOT_FROM_NSISUPPORTS , "Failed to build a wrapper because the interface does not inherit from nsISupports")
|
||||
|
||||
/* common global codes (from nsError.h) */
|
||||
|
||||
|
@ -195,7 +195,7 @@ nsXPCInterfaces::FillCache(JSContext *cx, JSObject *obj,
|
||||
}
|
||||
|
||||
rv = is_Interface->
|
||||
QueryInterface(nsCOMTypeInfo<nsIInterfaceInfo>::GetIID(),
|
||||
QueryInterface(NS_GET_IID(nsIInterfaceInfo),
|
||||
(void **)&Interface);
|
||||
|
||||
if(!NS_FAILED(rv))
|
||||
|
@ -359,7 +359,7 @@ XPCConvert::NativeData2JS(JSContext* cx, jsval* d, const void* s,
|
||||
!(xpcc = nsXPConnect::GetContext(cx)) ||
|
||||
!(wrapper =
|
||||
nsXPCWrappedNative::GetNewOrUsedWrapper(xpcc,
|
||||
iface, *iid)))
|
||||
iface, *iid, pErr)))
|
||||
{
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
@ -640,7 +640,7 @@ CIDCreateInstance::Call(JSContext *cx, JSObject *obj,
|
||||
// the security manager vetoed. It should have set an exception.
|
||||
nsAllocator::Free(cid);
|
||||
*rval = JSVAL_NULL;
|
||||
*retval = JS_TRUE;
|
||||
*retval = JS_FALSE;
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
@ -841,7 +841,7 @@ CIDGetService::Call(JSContext *cx, JSObject *obj,
|
||||
// the security manager vetoed. It should have set an exception.
|
||||
nsAllocator::Free(cid);
|
||||
*rval = JSVAL_NULL;
|
||||
*retval = JS_TRUE;
|
||||
*retval = JS_FALSE;
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
@ -34,9 +34,7 @@
|
||||
|
||||
/* Module level methods. */
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "xpcprivate.h"
|
||||
#include "nsIModule.h"
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
|
@ -53,6 +53,8 @@
|
||||
#include "nsIXPCScriptable.h"
|
||||
#include "nsIXPCSecurityManager.h"
|
||||
#include "nsIJSRuntimeService.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIModule.h"
|
||||
#include "xptcall.h"
|
||||
#include "jsapi.h"
|
||||
#include "jshash.h"
|
||||
@ -167,7 +169,7 @@ public:
|
||||
static nsIInterfaceInfoManager* GetInterfaceInfoManager(nsXPConnect* xpc = nsnull);
|
||||
static XPCContext* GetContext(JSContext* cx, nsXPConnect* xpc = nsnull);
|
||||
static XPCJSThrower* GetJSThrower(nsXPConnect* xpc = nsnull);
|
||||
static JSBool IsISupportsDescendent(nsIInterfaceInfo* info);
|
||||
static JSBool IsISupportsDescendant(nsIInterfaceInfo* info);
|
||||
static nsIJSContextStack* GetContextStack(nsXPConnect* xpc = nsnull);
|
||||
|
||||
JSContext2XPCContextMap* GetContextMap() {return mContextMap;}
|
||||
@ -623,7 +625,8 @@ class nsXPCWrappedNativeClass : public nsIXPCWrappedNativeClass
|
||||
NS_IMETHOD DebugDump(int depth);
|
||||
public:
|
||||
static nsXPCWrappedNativeClass* GetNewOrUsedClass(XPCContext* xpcc,
|
||||
REFNSIID aIID);
|
||||
REFNSIID aIID,
|
||||
nsresult* pErr);
|
||||
|
||||
REFNSIID GetIID() const {return mIID;}
|
||||
const char* GetInterfaceName();
|
||||
@ -784,7 +787,8 @@ class nsXPCWrappedNative : public nsIXPConnectWrappedNative
|
||||
public:
|
||||
static nsXPCWrappedNative* GetNewOrUsedWrapper(XPCContext* xpcc,
|
||||
nsISupports* aObj,
|
||||
REFNSIID aIID);
|
||||
REFNSIID aIID,
|
||||
nsresult* pErr);
|
||||
nsISupports* GetNative() const {return mObj;}
|
||||
JSObject* GetJSObject() const {return mJSObj;}
|
||||
nsXPCWrappedNativeClass* GetClass() const {return mClass;}
|
||||
|
@ -197,6 +197,11 @@ void
|
||||
XPCJSThrower::BuildAndThrowException(JSContext* cx, nsresult rv, const char* sz)
|
||||
{
|
||||
JSBool success = JS_FALSE;
|
||||
|
||||
/* no need to set an expection if the security manager already has */
|
||||
if(rv == NS_ERROR_XPC_SECURITY_MANAGER_VETO && JS_IsExceptionPending(cx))
|
||||
return;
|
||||
|
||||
nsIXPCException* e = nsXPCException::NewException(sz, rv, nsnull, nsnull);
|
||||
|
||||
if(e)
|
||||
|
@ -160,7 +160,7 @@ nsXPCWrappedJS::GetNewOrUsedWrapper(XPCContext* xpcc,
|
||||
// just a root wrapper
|
||||
nsXPCWrappedJSClass* rootClazz;
|
||||
rootClazz = nsXPCWrappedJSClass::GetNewOrUsedClass(
|
||||
xpcc, nsCOMTypeInfo<nsISupports>::GetIID());
|
||||
xpcc, NS_GET_IID(nsISupports));
|
||||
if(!rootClazz)
|
||||
goto return_wrapper;
|
||||
|
||||
@ -261,7 +261,7 @@ nsXPCWrappedJS::~nsXPCWrappedJS()
|
||||
nsXPCWrappedJS*
|
||||
nsXPCWrappedJS::Find(REFNSIID aIID)
|
||||
{
|
||||
if(aIID.Equals(nsCOMTypeInfo<nsISupports>::GetIID()))
|
||||
if(aIID.Equals(NS_GET_IID(nsISupports)))
|
||||
return mRoot;
|
||||
|
||||
nsXPCWrappedJS* cur = mRoot;
|
||||
|
@ -69,7 +69,7 @@ nsXPCWrappedJSClass::GetNewOrUsedClass(XPCContext* xpcc,
|
||||
nsIInterfaceInfo* info;
|
||||
if(NS_SUCCEEDED(iimgr->GetInfoForIID(&aIID, &info)))
|
||||
{
|
||||
if(nsXPConnect::IsISupportsDescendent(info))
|
||||
if(nsXPConnect::IsISupportsDescendant(info))
|
||||
{
|
||||
clazz = new nsXPCWrappedJSClass(xpcc, aIID, info);
|
||||
if(!clazz->mDescriptors)
|
||||
@ -294,7 +294,8 @@ nsXPCWrappedJSClass::DelegatedQueryInterface(nsXPCWrappedJS* self,
|
||||
JSObject*
|
||||
nsXPCWrappedJSClass::GetRootJSObject(JSObject* aJSObj)
|
||||
{
|
||||
JSObject* result = CallQueryInterfaceOnJSObject(aJSObj, nsCOMTypeInfo<nsISupports>::GetIID());
|
||||
JSObject* result = CallQueryInterfaceOnJSObject(aJSObj,
|
||||
NS_GET_IID(nsISupports));
|
||||
return result ? result : aJSObj;
|
||||
}
|
||||
|
||||
|
@ -91,11 +91,14 @@ nsXPCWrappedNative::JSObjectFinalized(JSContext *cx, JSObject *obj)
|
||||
Release();
|
||||
}
|
||||
|
||||
#define SET_ERROR_CODE(_y) if(pErr) *pErr = _y
|
||||
|
||||
// static
|
||||
nsXPCWrappedNative*
|
||||
nsXPCWrappedNative::GetNewOrUsedWrapper(XPCContext* xpcc,
|
||||
nsISupports* aObj,
|
||||
REFNSIID aIID)
|
||||
REFNSIID aIID,
|
||||
nsresult* pErr)
|
||||
{
|
||||
Native2WrappedNativeMap* map;
|
||||
nsISupports* rootObj = nsnull;
|
||||
@ -107,6 +110,8 @@ nsXPCWrappedNative::GetNewOrUsedWrapper(XPCContext* xpcc,
|
||||
NS_PRECONDITION(xpcc, "bad param");
|
||||
NS_PRECONDITION(aObj, "bad param");
|
||||
|
||||
SET_ERROR_CODE(NS_ERROR_FAILURE);
|
||||
|
||||
map = xpcc->GetWrappedNativeMap();
|
||||
if(!map)
|
||||
{
|
||||
@ -116,7 +121,8 @@ nsXPCWrappedNative::GetNewOrUsedWrapper(XPCContext* xpcc,
|
||||
|
||||
// always find the native root
|
||||
|
||||
if(NS_FAILED(aObj->QueryInterface(nsCOMTypeInfo<nsISupports>::GetIID(), (void**)&rootObj)))
|
||||
if(NS_FAILED(aObj->QueryInterface(NS_GET_IID(nsISupports),
|
||||
(void**)&rootObj)))
|
||||
goto return_wrapper;
|
||||
|
||||
// look for the root wrapper
|
||||
@ -148,12 +154,13 @@ nsXPCWrappedNative::GetNewOrUsedWrapper(XPCContext* xpcc,
|
||||
NS_OK != sm->CanCreateWrapper(xpcc->GetJSContext(), aIID, realObj))
|
||||
{
|
||||
// the security manager vetoed. It should have set an exception.
|
||||
SET_ERROR_CODE(NS_ERROR_XPC_SECURITY_MANAGER_VETO);
|
||||
goto return_wrapper;
|
||||
}
|
||||
|
||||
// need to make a wrapper
|
||||
|
||||
clazz = nsXPCWrappedNativeClass::GetNewOrUsedClass(xpcc, aIID);
|
||||
clazz = nsXPCWrappedNativeClass::GetNewOrUsedClass(xpcc, aIID, pErr);
|
||||
if(!clazz)
|
||||
goto return_wrapper;
|
||||
|
||||
@ -181,7 +188,7 @@ nsXPCWrappedNative::GetNewOrUsedWrapper(XPCContext* xpcc,
|
||||
// just a root wrapper
|
||||
nsXPCWrappedNativeClass* rootClazz;
|
||||
rootClazz = nsXPCWrappedNativeClass::GetNewOrUsedClass(
|
||||
xpcc, nsCOMTypeInfo<nsISupports>::GetIID());
|
||||
xpcc, NS_GET_IID(nsISupports), pErr);
|
||||
if(!rootClazz)
|
||||
goto return_wrapper;
|
||||
|
||||
@ -230,6 +237,9 @@ return_wrapper:
|
||||
NS_RELEASE(realObj);
|
||||
if(clazz)
|
||||
NS_RELEASE(clazz);
|
||||
|
||||
if(wrapper)
|
||||
SET_ERROR_CODE(NS_OK);
|
||||
return wrapper;
|
||||
}
|
||||
|
||||
@ -354,7 +364,7 @@ nsXPCWrappedNative::~nsXPCWrappedNative()
|
||||
nsXPCWrappedNative*
|
||||
nsXPCWrappedNative::Find(REFNSIID aIID)
|
||||
{
|
||||
if(aIID.Equals(nsCOMTypeInfo<nsISupports>::GetIID()))
|
||||
if(aIID.Equals(NS_GET_IID(nsISupports)))
|
||||
return mRoot;
|
||||
|
||||
nsXPCWrappedNative* cur = mRoot;
|
||||
|
@ -47,10 +47,13 @@ extern "C" JS_IMPORT_DATA(JSObjectOps) js_ObjectOps;
|
||||
|
||||
NS_IMPL_ISUPPORTS1(nsXPCWrappedNativeClass, nsIXPCWrappedNativeClass)
|
||||
|
||||
#define SET_ERROR_CODE(_y) if(pErr) *pErr = _y
|
||||
|
||||
// static
|
||||
nsXPCWrappedNativeClass*
|
||||
nsXPCWrappedNativeClass::GetNewOrUsedClass(XPCContext* xpcc,
|
||||
REFNSIID aIID)
|
||||
REFNSIID aIID,
|
||||
nsresult* pErr)
|
||||
{
|
||||
IID2WrappedNativeClassMap* map;
|
||||
nsXPCWrappedNativeClass* clazz = nsnull;
|
||||
@ -60,32 +63,53 @@ nsXPCWrappedNativeClass::GetNewOrUsedClass(XPCContext* xpcc,
|
||||
map = xpcc->GetWrappedNativeClassMap();
|
||||
NS_ASSERTION(map,"bad map");
|
||||
|
||||
SET_ERROR_CODE(NS_OK);
|
||||
|
||||
clazz = map->Find(aIID);
|
||||
if(clazz)
|
||||
{
|
||||
NS_ADDREF(clazz);
|
||||
return clazz;
|
||||
}
|
||||
else
|
||||
|
||||
nsCOMPtr<nsIInterfaceInfoManager> iimgr;
|
||||
if(!(iimgr = nsXPConnect::GetInterfaceInfoManager()))
|
||||
{
|
||||
nsIInterfaceInfoManager* iimgr;
|
||||
if(nsnull != (iimgr = nsXPConnect::GetInterfaceInfoManager()))
|
||||
{
|
||||
nsIInterfaceInfo* info;
|
||||
if(NS_SUCCEEDED(iimgr->GetInfoForIID(&aIID, &info)))
|
||||
{
|
||||
PRBool canScript;
|
||||
if(NS_SUCCEEDED(info->IsScriptable(&canScript)) &&
|
||||
canScript &&
|
||||
nsXPConnect::IsISupportsDescendent(info))
|
||||
{
|
||||
clazz = new nsXPCWrappedNativeClass(xpcc, aIID, info);
|
||||
if(-1 == clazz->mMemberCount) // -1 means 'failed to init'
|
||||
NS_RELEASE(clazz); // nsnulls out 'clazz'
|
||||
}
|
||||
NS_RELEASE(info);
|
||||
}
|
||||
NS_RELEASE(iimgr);
|
||||
}
|
||||
SET_ERROR_CODE(NS_ERROR_FAILURE);
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIInterfaceInfo> info;
|
||||
if(NS_FAILED(iimgr->GetInfoForIID(&aIID, getter_AddRefs(info))))
|
||||
{
|
||||
SET_ERROR_CODE(NS_ERROR_XPC_CANT_GET_INTERFACE_INFO);
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
PRBool canScript;
|
||||
if(NS_FAILED(info->IsScriptable(&canScript)))
|
||||
{
|
||||
SET_ERROR_CODE(NS_ERROR_FAILURE);
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
if(!canScript)
|
||||
{
|
||||
SET_ERROR_CODE(NS_ERROR_XPC_INTERFACE_NOT_SCRIPTABLE);
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
if(!nsXPConnect::IsISupportsDescendant(info))
|
||||
{
|
||||
SET_ERROR_CODE(NS_ERROR_XPC_INTERFACE_NOT_FROM_NSISUPPORTS);
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
clazz = new nsXPCWrappedNativeClass(xpcc, aIID, info);
|
||||
if(-1 == clazz->mMemberCount) // -1 means 'failed to init'
|
||||
{
|
||||
SET_ERROR_CODE(NS_ERROR_FAILURE);
|
||||
NS_RELEASE(clazz); // nsnulls out 'clazz'
|
||||
}
|
||||
return clazz;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user