mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-16 06:45:42 +00:00
Bug 627954, part 2: ensure nsXPCConvert::VariantData2JS et al are in the correct compartment (r=mrbkap)
--HG-- extra : rebase_source : c924f5e87e2f5a6339f4c83c78db1c7f05b600f7
This commit is contained in:
parent
3cfb03a5ab
commit
bbfde362e9
@ -25,7 +25,7 @@ load 348049-1.xhtml
|
||||
load 344882-1.html
|
||||
load 345837-1.xhtml
|
||||
load 349355-1.html
|
||||
asserts(1) load 354645-1.xul # bug 512815
|
||||
load 354645-1.xul
|
||||
load 360599-1.html
|
||||
load 366200-1.xhtml
|
||||
load 369216-1.html
|
||||
|
@ -1093,6 +1093,7 @@ nsXPConnect::InitClassesWithNewWrappedGlobal(JSContext * aJSContext,
|
||||
JSAutoEnterCompartment ac;
|
||||
if(!ac.enter(ccx, tempGlobal))
|
||||
return UnexpectedFailure(NS_ERROR_FAILURE);
|
||||
ccx.SetScopeForNewJSObjects(tempGlobal);
|
||||
|
||||
PRBool system = (aFlags & nsIXPConnect::FLAG_SYSTEM_GLOBAL_OBJECT) != 0;
|
||||
if(system && !JS_MakeSystemObject(aJSContext, tempGlobal))
|
||||
@ -1113,8 +1114,7 @@ nsXPConnect::InitClassesWithNewWrappedGlobal(JSContext * aJSContext,
|
||||
if(!XPCConvert::NativeInterface2JSObject(ccx, &v,
|
||||
getter_AddRefs(holder),
|
||||
helper, &aIID, nsnull,
|
||||
tempGlobal, PR_FALSE,
|
||||
OBJ_IS_GLOBAL, &rv))
|
||||
PR_FALSE, OBJ_IS_GLOBAL, &rv))
|
||||
return UnexpectedFailure(rv);
|
||||
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv) && holder, "Didn't wrap properly");
|
||||
@ -1207,10 +1207,16 @@ NativeInterface2JSObject(XPCLazyCallContext & lccx,
|
||||
jsval *aVal,
|
||||
nsIXPConnectJSObjectHolder **aHolder)
|
||||
{
|
||||
JSAutoEnterCompartment ac;
|
||||
if (!ac.enter(lccx.GetJSContext(), aScope))
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
lccx.SetScopeForNewJSObjects(aScope);
|
||||
|
||||
nsresult rv;
|
||||
xpcObjectHelper helper(aCOMObj, aCache);
|
||||
if(!XPCConvert::NativeInterface2JSObject(lccx, aVal, aHolder, helper, aIID,
|
||||
nsnull, aScope, aAllowWrapping,
|
||||
nsnull, aAllowWrapping,
|
||||
OBJ_IS_NOT_GLOBAL, &rv))
|
||||
return rv;
|
||||
|
||||
@ -2273,8 +2279,10 @@ nsXPConnect::VariantToJS(JSContext* ctx, JSObject* scope, nsIVariant* value, jsv
|
||||
return NS_ERROR_FAILURE;
|
||||
XPCLazyCallContext lccx(ccx);
|
||||
|
||||
ccx.SetScopeForNewJSObjects(scope);
|
||||
|
||||
nsresult rv = NS_OK;
|
||||
if(!XPCVariant::VariantDataToJS(lccx, value, scope, &rv, _retval))
|
||||
if(!XPCVariant::VariantDataToJS(lccx, value, &rv, _retval))
|
||||
{
|
||||
if(NS_FAILED(rv))
|
||||
return rv;
|
||||
|
@ -57,18 +57,17 @@ XPCCallContext::XPCCallContext(XPCContext::LangType callerLanguage,
|
||||
mJSContext(cx),
|
||||
mContextPopRequired(JS_FALSE),
|
||||
mDestroyJSContextInDestructor(JS_FALSE),
|
||||
mCallerLanguage(callerLanguage),
|
||||
mCallee(nsnull)
|
||||
mCallerLanguage(callerLanguage)
|
||||
{
|
||||
Init(callerLanguage, callerLanguage == NATIVE_CALLER, obj, funobj, JS_TRUE,
|
||||
name, argc, argv, rval);
|
||||
Init(callerLanguage, callerLanguage == NATIVE_CALLER, obj, funobj,
|
||||
INIT_SHOULD_LOOKUP_WRAPPER, name, argc, argv, rval);
|
||||
}
|
||||
|
||||
XPCCallContext::XPCCallContext(XPCContext::LangType callerLanguage,
|
||||
JSContext* cx,
|
||||
JSBool callBeginRequest,
|
||||
JSObject* obj,
|
||||
JSObject* currentJSObject,
|
||||
JSObject* flattenedJSObject,
|
||||
XPCWrappedNative* wrapper,
|
||||
XPCWrappedNativeTearOff* tearOff)
|
||||
: mState(INIT_FAILED),
|
||||
@ -79,12 +78,12 @@ XPCCallContext::XPCCallContext(XPCContext::LangType callerLanguage,
|
||||
mContextPopRequired(JS_FALSE),
|
||||
mDestroyJSContextInDestructor(JS_FALSE),
|
||||
mCallerLanguage(callerLanguage),
|
||||
mCurrentJSObject(currentJSObject),
|
||||
mFlattenedJSObject(flattenedJSObject),
|
||||
mWrapper(wrapper),
|
||||
mTearOff(tearOff),
|
||||
mCallee(nsnull)
|
||||
mTearOff(tearOff)
|
||||
{
|
||||
Init(callerLanguage, callBeginRequest, obj, nsnull, JS_FALSE, JSID_VOID, NO_ARGS,
|
||||
Init(callerLanguage, callBeginRequest, obj, nsnull,
|
||||
WRAPPER_PASSED_TO_CONSTRUCTOR, JSID_VOID, NO_ARGS,
|
||||
nsnull, nsnull);
|
||||
}
|
||||
|
||||
@ -93,7 +92,7 @@ XPCCallContext::Init(XPCContext::LangType callerLanguage,
|
||||
JSBool callBeginRequest,
|
||||
JSObject* obj,
|
||||
JSObject* funobj,
|
||||
JSBool getWrappedNative,
|
||||
WrapperInitOptions wrapperInitOptions,
|
||||
jsid name,
|
||||
uintN argc,
|
||||
jsval *argv,
|
||||
@ -180,45 +179,38 @@ XPCCallContext::Init(XPCContext::LangType callerLanguage,
|
||||
if(!obj)
|
||||
return;
|
||||
|
||||
mScopeForNewJSObjects = obj;
|
||||
|
||||
mState = HAVE_SCOPE;
|
||||
|
||||
mMethodIndex = 0xDEAD;
|
||||
mOperandJSObject = obj;
|
||||
|
||||
mState = HAVE_OBJECT;
|
||||
|
||||
mTearOff = nsnull;
|
||||
|
||||
if(getWrappedNative)
|
||||
if(wrapperInitOptions == INIT_SHOULD_LOOKUP_WRAPPER)
|
||||
{
|
||||
mWrapper = XPCWrappedNative::GetWrappedNativeOfJSObject(mJSContext, obj,
|
||||
funobj,
|
||||
&mCurrentJSObject,
|
||||
&mFlattenedJSObject,
|
||||
&mTearOff);
|
||||
if(mWrapper)
|
||||
{
|
||||
DEBUG_CheckWrapperThreadSafety(mWrapper);
|
||||
|
||||
mFlattenedJSObject = mWrapper->GetFlatJSObjectAndMark();
|
||||
|
||||
if(mTearOff)
|
||||
if(mWrapper)
|
||||
{
|
||||
mCurrentJSObject = mTearOff->GetJSObject();
|
||||
mScriptableInfo = nsnull;
|
||||
DEBUG_CheckWrapperThreadSafety(mWrapper);
|
||||
|
||||
mFlattenedJSObject = mWrapper->GetFlatJSObjectAndMark();
|
||||
|
||||
if(mTearOff)
|
||||
mScriptableInfo = nsnull;
|
||||
else
|
||||
mScriptableInfo = mWrapper->GetScriptableInfo();
|
||||
}
|
||||
else
|
||||
{
|
||||
mWrapper->GetJSObject(&mCurrentJSObject);
|
||||
mScriptableInfo = mWrapper->GetScriptableInfo();
|
||||
NS_ABORT_IF_FALSE(!mFlattenedJSObject || IS_SLIM_WRAPPER(mFlattenedJSObject),
|
||||
"should have a slim wrapper");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(!mCurrentJSObject)
|
||||
return;
|
||||
|
||||
NS_ASSERTION(IS_SLIM_WRAPPER(mCurrentJSObject),
|
||||
"What kind of wrapper is this?");
|
||||
|
||||
mFlattenedJSObject = mCurrentJSObject;
|
||||
}
|
||||
|
||||
if(!JSID_IS_VOID(name))
|
||||
SetName(name);
|
||||
|
@ -239,13 +239,18 @@ INT64_TO_DOUBLE(const int64 &v)
|
||||
// static
|
||||
JSBool
|
||||
XPCConvert::NativeData2JS(XPCLazyCallContext& lccx, jsval* d, const void* s,
|
||||
const nsXPTType& type, const nsID* iid,
|
||||
JSObject* scope, nsresult* pErr)
|
||||
const nsXPTType& type, const nsID* iid, nsresult* pErr)
|
||||
{
|
||||
NS_PRECONDITION(s, "bad param");
|
||||
NS_PRECONDITION(d, "bad param");
|
||||
|
||||
JSContext* cx = lccx.GetJSContext();
|
||||
JSContext* cx = lccx.GetJSContext();
|
||||
|
||||
// Allow wrong compartment or unset ScopeForNewObject when the caller knows
|
||||
// the value is primitive (viz., XPCNativeMember::GetConstantValue).
|
||||
NS_ABORT_IF_FALSE(type.IsArithmetic() ||
|
||||
cx->compartment == lccx.GetScopeForNewJSObjects()->compartment(),
|
||||
"bad scope for new JSObjects");
|
||||
|
||||
if(pErr)
|
||||
*pErr = NS_ERROR_XPC_BAD_CONVERT_NATIVE;
|
||||
@ -294,18 +299,6 @@ XPCConvert::NativeData2JS(XPCLazyCallContext& lccx, jsval* d, const void* s,
|
||||
case nsXPTType::T_JSVAL :
|
||||
{
|
||||
*d = *((jsval*)s);
|
||||
|
||||
JSAutoEnterCompartment ac;
|
||||
XPCCallContext &ccx = lccx.GetXPCCallContext();
|
||||
if(ccx.GetXPCContext()->CallerTypeIsNative())
|
||||
{
|
||||
JSObject *jsscope = ccx.GetCallee();
|
||||
if(!jsscope || !JS_ObjectIsFunction(ccx, jsscope))
|
||||
jsscope = JS_GetGlobalForObject(ccx, scope);
|
||||
if(!ac.enter(ccx, jsscope))
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
if(!JS_WrapValue(cx, d))
|
||||
return JS_FALSE;
|
||||
break;
|
||||
@ -333,7 +326,7 @@ XPCConvert::NativeData2JS(XPCLazyCallContext& lccx, jsval* d, const void* s,
|
||||
if(!iid2)
|
||||
break;
|
||||
JSObject* obj;
|
||||
if(!(obj = xpc_NewIDObject(cx, scope, *iid2)))
|
||||
if(!(obj = xpc_NewIDObject(cx, lccx.GetScopeForNewJSObjects(), *iid2)))
|
||||
return JS_FALSE;
|
||||
*d = OBJECT_TO_JSVAL(obj);
|
||||
break;
|
||||
@ -479,7 +472,7 @@ XPCConvert::NativeData2JS(XPCLazyCallContext& lccx, jsval* d, const void* s,
|
||||
return JS_FALSE;
|
||||
|
||||
return XPCVariant::VariantDataToJS(lccx, variant,
|
||||
scope, pErr, d);
|
||||
pErr, d);
|
||||
}
|
||||
// else...
|
||||
|
||||
@ -490,7 +483,7 @@ XPCConvert::NativeData2JS(XPCLazyCallContext& lccx, jsval* d, const void* s,
|
||||
// creating a new XPCNativeScriptableShared.
|
||||
xpcObjectHelper helper(iface);
|
||||
if(!NativeInterface2JSObject(lccx, d, nsnull, helper, iid,
|
||||
nsnull, scope, PR_TRUE,
|
||||
nsnull, PR_TRUE,
|
||||
OBJ_IS_NOT_GLOBAL, pErr))
|
||||
return JS_FALSE;
|
||||
|
||||
@ -1113,34 +1106,6 @@ CreateHolderIfNeeded(XPCCallContext& ccx, JSObject* obj, jsval* d,
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
static PRBool
|
||||
ComputeWrapperInfo(const XPCCallContext &ccx, XPCWrappedNativeScope *scope,
|
||||
JSObject **callee)
|
||||
{
|
||||
if(ccx.GetXPCContext()->CallerTypeIsJavaScript())
|
||||
{
|
||||
// Called from JS. We're going to hand the resulting JSObject
|
||||
// to said JS. The correct compartment must already be pushed
|
||||
// on cx, so return true and don't give back a callee.
|
||||
*callee = nsnull;
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
if(ccx.GetXPCContext()->CallerTypeIsNative())
|
||||
{
|
||||
// Calling from JS -> C++, return false to indicate that we need
|
||||
// to push a compartment and return the callee.
|
||||
*callee = ccx.GetCallee();
|
||||
if(!*callee || !JS_ObjectIsFunction(ccx, *callee))
|
||||
{
|
||||
*callee = scope->GetGlobalJSObject();
|
||||
OBJ_TO_INNER_OBJECT(ccx, *callee);
|
||||
}
|
||||
}
|
||||
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
// static
|
||||
JSBool
|
||||
@ -1150,12 +1115,10 @@ XPCConvert::NativeInterface2JSObject(XPCLazyCallContext& lccx,
|
||||
xpcObjectHelper& aHelper,
|
||||
const nsID* iid,
|
||||
XPCNativeInterface** Interface,
|
||||
JSObject* scope,
|
||||
PRBool allowNativeWrapper,
|
||||
PRBool isGlobal,
|
||||
nsresult* pErr)
|
||||
{
|
||||
NS_ASSERTION(scope, "bad param");
|
||||
NS_ASSERTION(!Interface || iid,
|
||||
"Need the iid if you pass in an XPCNativeInterface cache.");
|
||||
|
||||
@ -1176,9 +1139,12 @@ XPCConvert::NativeInterface2JSObject(XPCLazyCallContext& lccx,
|
||||
// optimal -- we could detect this and roll the functionality into a
|
||||
// single wrapper, but the current solution is good enough for now.
|
||||
JSContext* cx = lccx.GetJSContext();
|
||||
NS_ABORT_IF_FALSE(lccx.GetScopeForNewJSObjects()->compartment() == cx->compartment,
|
||||
"bad scope for new JSObjects");
|
||||
|
||||
JSObject *jsscope = lccx.GetScopeForNewJSObjects();
|
||||
XPCWrappedNativeScope* xpcscope =
|
||||
XPCWrappedNativeScope::FindInJSObjectScope(cx, scope);
|
||||
XPCWrappedNativeScope::FindInJSObjectScope(cx, jsscope);
|
||||
if(!xpcscope)
|
||||
return JS_FALSE;
|
||||
|
||||
@ -1190,8 +1156,6 @@ XPCConvert::NativeInterface2JSObject(XPCLazyCallContext& lccx,
|
||||
// object will create (and fill the cache) from its PreCreate call.
|
||||
nsWrapperCache *cache = aHelper.GetWrapperCache();
|
||||
|
||||
JSObject *callee;
|
||||
|
||||
PRBool tryConstructSlimWrapper = PR_FALSE;
|
||||
JSObject *flat;
|
||||
if(cache)
|
||||
@ -1206,13 +1170,6 @@ XPCConvert::NativeInterface2JSObject(XPCLazyCallContext& lccx,
|
||||
if(!flat)
|
||||
flat = ConstructProxyObject(ccx, aHelper, xpcscope);
|
||||
|
||||
JSAutoEnterCompartment ac;
|
||||
if(!ComputeWrapperInfo(ccx, xpcscope, &callee) &&
|
||||
!ac.enter(ccx, callee))
|
||||
{
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
if(!JS_WrapObject(ccx, &flat))
|
||||
return JS_FALSE;
|
||||
|
||||
@ -1368,13 +1325,6 @@ XPCConvert::NativeInterface2JSObject(XPCLazyCallContext& lccx,
|
||||
if(!ccx.IsValid())
|
||||
return JS_FALSE;
|
||||
|
||||
JSAutoEnterCompartment ac;
|
||||
if(!ComputeWrapperInfo(ccx, xpcscope, &callee) &&
|
||||
!ac.enter(ccx, callee))
|
||||
{
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
JSObject *original = flat;
|
||||
if(!JS_WrapObject(ccx, &flat))
|
||||
return JS_FALSE;
|
||||
@ -1959,8 +1909,8 @@ XPC_JSArgumentFormatter(JSContext *cx, const char *format,
|
||||
// NOTE: MUST be retrieved *after* the iid in the 'p' case above.
|
||||
p = va_arg(ap, void *);
|
||||
|
||||
if(!XPCConvert::NativeData2JS(ccx, &vp[0], &p, type, iid,
|
||||
JS_GetGlobalObject(cx), nsnull))
|
||||
ccx.SetScopeForNewJSObjects(JS_GetGlobalForScopeChain(cx));
|
||||
if(!XPCConvert::NativeData2JS(ccx, &vp[0], &p, type, iid, nsnull))
|
||||
return JS_FALSE;
|
||||
}
|
||||
*vpp = vp + 1;
|
||||
@ -1981,8 +1931,7 @@ JSBool
|
||||
XPCConvert::NativeArray2JS(XPCLazyCallContext& lccx,
|
||||
jsval* d, const void** s,
|
||||
const nsXPTType& type, const nsID* iid,
|
||||
JSUint32 count, JSObject* scope,
|
||||
nsresult* pErr)
|
||||
JSUint32 count, nsresult* pErr)
|
||||
{
|
||||
NS_PRECONDITION(s, "bad param");
|
||||
NS_PRECONDITION(d, "bad param");
|
||||
@ -1992,6 +1941,8 @@ XPCConvert::NativeArray2JS(XPCLazyCallContext& lccx,
|
||||
return JS_FALSE;
|
||||
|
||||
JSContext* cx = ccx.GetJSContext();
|
||||
NS_ABORT_IF_FALSE(lccx.GetScopeForNewJSObjects()->compartment() == cx->compartment,
|
||||
"bad scope for new JSObjects");
|
||||
|
||||
// XXX add support for putting chars in a string rather than an array
|
||||
|
||||
@ -2017,8 +1968,7 @@ XPCConvert::NativeArray2JS(XPCLazyCallContext& lccx,
|
||||
PR_BEGIN_MACRO \
|
||||
for(i = 0; i < count; i++) \
|
||||
{ \
|
||||
if(!NativeData2JS(ccx, ¤t, ((_t*)*s)+i, type, iid, \
|
||||
scope, pErr) || \
|
||||
if(!NativeData2JS(ccx, ¤t, ((_t*)*s)+i, type, iid, pErr) ||\
|
||||
!JS_SetElement(cx, array, i, ¤t)) \
|
||||
goto failure; \
|
||||
} \
|
||||
|
@ -157,17 +157,19 @@ XPCCallContext::GetPrevCallContext() const
|
||||
}
|
||||
|
||||
inline JSObject*
|
||||
XPCCallContext::GetOperandJSObject() const
|
||||
XPCCallContext::GetScopeForNewJSObjects() const
|
||||
{
|
||||
CHECK_STATE(HAVE_OBJECT);
|
||||
return mOperandJSObject;
|
||||
CHECK_STATE(HAVE_SCOPE);
|
||||
return mScopeForNewJSObjects;
|
||||
}
|
||||
|
||||
inline JSObject*
|
||||
XPCCallContext::GetCurrentJSObject() const
|
||||
inline void
|
||||
XPCCallContext::SetScopeForNewJSObjects(JSObject *scope)
|
||||
{
|
||||
CHECK_STATE(HAVE_OBJECT);
|
||||
return mCurrentJSObject;
|
||||
NS_ABORT_IF_FALSE(mState == HAVE_CONTEXT, "wrong call context state");
|
||||
NS_ABORT_IF_FALSE(scope->compartment() == mJSContext->compartment, "wrong compartment");
|
||||
mScopeForNewJSObjects = scope;
|
||||
mState = HAVE_SCOPE;
|
||||
}
|
||||
|
||||
inline JSObject*
|
||||
@ -183,8 +185,8 @@ XPCCallContext::GetIdentityObject() const
|
||||
CHECK_STATE(HAVE_OBJECT);
|
||||
if(mWrapper)
|
||||
return mWrapper->GetIdentityObject();
|
||||
return mCurrentJSObject ?
|
||||
static_cast<nsISupports*>(xpc_GetJSPrivate(mCurrentJSObject)) :
|
||||
return mFlattenedJSObject ?
|
||||
static_cast<nsISupports*>(xpc_GetJSPrivate(mFlattenedJSObject)) :
|
||||
nsnull;
|
||||
}
|
||||
|
||||
@ -204,7 +206,7 @@ XPCCallContext::GetProto() const
|
||||
CHECK_STATE(HAVE_OBJECT);
|
||||
if(mWrapper)
|
||||
return mWrapper->GetProto();
|
||||
return mCurrentJSObject ? GetSlimWrapperProto(mCurrentJSObject) : nsnull;
|
||||
return mFlattenedJSObject ? GetSlimWrapperProto(mFlattenedJSObject) : nsnull;
|
||||
}
|
||||
|
||||
inline JSBool
|
||||
@ -348,22 +350,6 @@ XPCCallContext::SetResolvingWrapper(XPCWrappedNative* w)
|
||||
return mThreadData->SetResolvingWrapper(w);
|
||||
}
|
||||
|
||||
inline JSObject*
|
||||
XPCCallContext::GetCallee() const
|
||||
{
|
||||
NS_ASSERTION(mCallerLanguage == NATIVE_CALLER,
|
||||
"GetCallee() doesn't make sense");
|
||||
return mCallee;
|
||||
}
|
||||
|
||||
inline void
|
||||
XPCCallContext::SetCallee(JSObject* callee)
|
||||
{
|
||||
NS_ASSERTION(mCallerLanguage == NATIVE_CALLER,
|
||||
"SetCallee() doesn't make sense");
|
||||
mCallee = callee;
|
||||
}
|
||||
|
||||
inline PRUint16
|
||||
XPCCallContext::GetMethodIndex() const
|
||||
{
|
||||
@ -803,18 +789,18 @@ XPCLazyCallContext::SetWrapper(XPCWrappedNative* wrapper,
|
||||
mWrapper = wrapper;
|
||||
mTearOff = tearoff;
|
||||
if(mTearOff)
|
||||
mCurrentJSObject = mTearOff->GetJSObject();
|
||||
mFlattenedJSObject = mTearOff->GetJSObject();
|
||||
else
|
||||
mWrapper->GetJSObject(&mCurrentJSObject);
|
||||
mFlattenedJSObject = mWrapper->GetFlatJSObjectAndMark();
|
||||
}
|
||||
inline void
|
||||
XPCLazyCallContext::SetWrapper(JSObject* currentJSObject)
|
||||
XPCLazyCallContext::SetWrapper(JSObject* flattenedJSObject)
|
||||
{
|
||||
NS_ASSERTION(IS_SLIM_WRAPPER_OBJECT(currentJSObject),
|
||||
NS_ASSERTION(IS_SLIM_WRAPPER_OBJECT(flattenedJSObject),
|
||||
"What kind of object is this?");
|
||||
mWrapper = nsnull;
|
||||
mTearOff = nsnull;
|
||||
mCurrentJSObject = currentJSObject;
|
||||
mFlattenedJSObject = flattenedJSObject;
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
|
@ -66,6 +66,7 @@
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsCycleCollectionParticipant.h"
|
||||
#include "nsCycleCollector.h"
|
||||
#include "nsDebug.h"
|
||||
#include "nsISupports.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsIClassInfoImpl.h"
|
||||
@ -1095,10 +1096,18 @@ public:
|
||||
inline XPCContext::LangType GetPrevCallerLanguage() const ;
|
||||
inline XPCCallContext* GetPrevCallContext() const ;
|
||||
|
||||
inline JSObject* GetOperandJSObject() const ;
|
||||
inline JSObject* GetCurrentJSObject() const ;
|
||||
inline JSObject* GetFlattenedJSObject() const ;
|
||||
/*
|
||||
* The 'scope for new JSObjects' will be the scope for objects created when
|
||||
* carrying out a JS/C++ call. This member is only available if HAVE_SCOPE.
|
||||
* The object passed to the ccx constructor is used as the scope for new
|
||||
* JSObjects. However, this object is also queried for a wrapper, so
|
||||
* clients that don't want a wrapper (and thus pass NULL to the ccx
|
||||
* constructor) need to manually call SetScopeForNewJSObjects.
|
||||
*/
|
||||
inline JSObject* GetScopeForNewJSObjects() const ;
|
||||
inline void SetScopeForNewJSObjects(JSObject *obj) ;
|
||||
|
||||
inline JSObject* GetFlattenedJSObject() const ;
|
||||
inline nsISupports* GetIdentityObject() const ;
|
||||
inline XPCWrappedNative* GetWrapper() const ;
|
||||
inline XPCWrappedNativeProto* GetProto() const ;
|
||||
@ -1134,9 +1143,6 @@ public:
|
||||
|
||||
inline void SetRetVal(jsval val);
|
||||
|
||||
inline JSObject* GetCallee() const;
|
||||
inline void SetCallee(JSObject* callee);
|
||||
|
||||
void SetName(jsid name);
|
||||
void SetArgsAndResultPtr(uintN argc, jsval *argv, jsval *rval);
|
||||
void SetCallInfo(XPCNativeInterface* iface, XPCNativeMember* member,
|
||||
@ -1171,15 +1177,20 @@ private:
|
||||
JSContext* cx,
|
||||
JSBool callBeginRequest,
|
||||
JSObject* obj,
|
||||
JSObject* currentJSObject,
|
||||
JSObject* flattenedJSObject,
|
||||
XPCWrappedNative* wn,
|
||||
XPCWrappedNativeTearOff* tearoff);
|
||||
|
||||
enum WrapperInitOptions {
|
||||
WRAPPER_PASSED_TO_CONSTRUCTOR,
|
||||
INIT_SHOULD_LOOKUP_WRAPPER
|
||||
};
|
||||
|
||||
void Init(XPCContext::LangType callerLanguage,
|
||||
JSBool callBeginRequest,
|
||||
JSObject* obj,
|
||||
JSObject* funobj,
|
||||
JSBool getWrappedNative,
|
||||
WrapperInitOptions wrapperInitOptions,
|
||||
jsid name,
|
||||
uintN argc,
|
||||
jsval *argv,
|
||||
@ -1191,6 +1202,7 @@ private:
|
||||
INIT_FAILED,
|
||||
SYSTEM_SHUTDOWN,
|
||||
HAVE_CONTEXT,
|
||||
HAVE_SCOPE,
|
||||
HAVE_OBJECT,
|
||||
HAVE_NAME,
|
||||
HAVE_ARGS,
|
||||
@ -1223,8 +1235,7 @@ private:
|
||||
|
||||
XPCCallContext* mPrevCallContext;
|
||||
|
||||
JSObject* mOperandJSObject;
|
||||
JSObject* mCurrentJSObject;
|
||||
JSObject* mScopeForNewJSObjects;
|
||||
JSObject* mFlattenedJSObject;
|
||||
XPCWrappedNative* mWrapper;
|
||||
XPCWrappedNativeTearOff* mTearOff;
|
||||
@ -1248,12 +1259,6 @@ private:
|
||||
#endif
|
||||
PRUint16 mMethodIndex;
|
||||
|
||||
// If not null, this is the function object of the function we're going to
|
||||
// call. This member only makes sense when CallerTypeIsNative() on our
|
||||
// XPCContext returns true. We're not responsible for rooting this object;
|
||||
// whoever sets it on us needs to deal with that.
|
||||
JSObject* mCallee;
|
||||
|
||||
#define XPCCCX_STRING_CACHE_SIZE 2
|
||||
|
||||
// String wrapper entry, holds a string, and a boolean that tells
|
||||
@ -1288,7 +1293,7 @@ public:
|
||||
, mCx(nsnull)
|
||||
, mCallerLanguage(JS_CALLER)
|
||||
, mObj(nsnull)
|
||||
, mCurrentJSObject(nsnull)
|
||||
, mFlattenedJSObject(nsnull)
|
||||
, mWrapper(nsnull)
|
||||
, mTearOff(nsnull)
|
||||
#endif
|
||||
@ -1296,7 +1301,7 @@ public:
|
||||
}
|
||||
XPCLazyCallContext(XPCContext::LangType callerLanguage, JSContext* cx,
|
||||
JSObject* obj = nsnull,
|
||||
JSObject* currentJSObject = nsnull,
|
||||
JSObject* flattenedJSObject = nsnull,
|
||||
XPCWrappedNative* wrapper = nsnull,
|
||||
XPCWrappedNativeTearOff* tearoff = nsnull)
|
||||
: mCallBeginRequest(callerLanguage == NATIVE_CALLER ?
|
||||
@ -1306,7 +1311,7 @@ public:
|
||||
mCx(cx),
|
||||
mCallerLanguage(callerLanguage),
|
||||
mObj(obj),
|
||||
mCurrentJSObject(currentJSObject),
|
||||
mFlattenedJSObject(flattenedJSObject),
|
||||
mWrapper(wrapper),
|
||||
mTearOff(tearoff)
|
||||
{
|
||||
@ -1327,7 +1332,7 @@ public:
|
||||
}
|
||||
void SetWrapper(XPCWrappedNative* wrapper,
|
||||
XPCWrappedNativeTearOff* tearoff);
|
||||
void SetWrapper(JSObject* currentJSObject);
|
||||
void SetWrapper(JSObject* flattenedJSObject);
|
||||
|
||||
JSContext *GetJSContext()
|
||||
{
|
||||
@ -1341,12 +1346,28 @@ public:
|
||||
|
||||
return mCx;
|
||||
}
|
||||
JSObject *GetCurrentJSObject() const
|
||||
JSObject *GetScopeForNewJSObjects() const
|
||||
{
|
||||
if(mCcx)
|
||||
return mCcx->GetCurrentJSObject();
|
||||
return mCcx->GetScopeForNewJSObjects();
|
||||
|
||||
return mCurrentJSObject;
|
||||
return mObj;
|
||||
}
|
||||
void SetScopeForNewJSObjects(JSObject *obj)
|
||||
{
|
||||
if(mCcx) {
|
||||
mCcx->SetScopeForNewJSObjects(obj);
|
||||
return;
|
||||
}
|
||||
NS_ABORT_IF_FALSE(!mObj, "already set!");
|
||||
mObj = obj;
|
||||
}
|
||||
JSObject *GetFlattenedJSObject() const
|
||||
{
|
||||
if(mCcx)
|
||||
return mCcx->GetFlattenedJSObject();
|
||||
|
||||
return mFlattenedJSObject;
|
||||
}
|
||||
XPCCallContext &GetXPCCallContext()
|
||||
{
|
||||
@ -1356,7 +1377,7 @@ public:
|
||||
new (mData) XPCCallContext(mCallerLanguage, mCx,
|
||||
mCallBeginRequest == CALL_BEGINREQUEST,
|
||||
mObj,
|
||||
mCurrentJSObject, mWrapper,
|
||||
mFlattenedJSObject, mWrapper,
|
||||
mTearOff);
|
||||
if(!mCcx->IsValid())
|
||||
{
|
||||
@ -1383,7 +1404,7 @@ private:
|
||||
JSContext *mCx;
|
||||
XPCContext::LangType mCallerLanguage;
|
||||
JSObject *mObj;
|
||||
JSObject *mCurrentJSObject;
|
||||
JSObject *mFlattenedJSObject;
|
||||
XPCWrappedNative *mWrapper;
|
||||
XPCWrappedNativeTearOff *mTearOff;
|
||||
char mData[sizeof(XPCCallContext)];
|
||||
@ -3205,15 +3226,14 @@ public:
|
||||
*/
|
||||
static JSBool NativeData2JS(XPCCallContext& ccx, jsval* d, const void* s,
|
||||
const nsXPTType& type, const nsID* iid,
|
||||
JSObject* scope, nsresult* pErr)
|
||||
nsresult* pErr)
|
||||
{
|
||||
XPCLazyCallContext lccx(ccx);
|
||||
return NativeData2JS(lccx, d, s, type, iid, scope, pErr);
|
||||
return NativeData2JS(lccx, d, s, type, iid, pErr);
|
||||
}
|
||||
static JSBool NativeData2JS(XPCLazyCallContext& lccx, jsval* d,
|
||||
const void* s, const nsXPTType& type,
|
||||
const nsID* iid, JSObject* scope,
|
||||
nsresult* pErr);
|
||||
const nsID* iid, nsresult* pErr);
|
||||
|
||||
static JSBool JSData2Native(XPCCallContext& ccx, void* d, jsval s,
|
||||
const nsXPTType& type,
|
||||
@ -3230,7 +3250,6 @@ public:
|
||||
* @param Interface the interface of src that we want
|
||||
* @param cache the wrapper cache for src (may be null, in which case src
|
||||
* will be QI'ed to get the cache)
|
||||
* @param scope the default scope to put on the new JSObject's parent chain
|
||||
* @param allowNativeWrapper if true, this method may wrap the resulting
|
||||
* JSObject in an XPCNativeWrapper and return that, as needed.
|
||||
* @param isGlobal
|
||||
@ -3244,15 +3263,13 @@ public:
|
||||
xpcObjectHelper& aHelper,
|
||||
const nsID* iid,
|
||||
XPCNativeInterface** Interface,
|
||||
JSObject* scope,
|
||||
PRBool allowNativeWrapper,
|
||||
PRBool isGlobal,
|
||||
nsresult* pErr)
|
||||
{
|
||||
XPCLazyCallContext lccx(ccx);
|
||||
return NativeInterface2JSObject(lccx, d, dest, aHelper, iid, Interface,
|
||||
scope, allowNativeWrapper, isGlobal,
|
||||
pErr);
|
||||
allowNativeWrapper, isGlobal, pErr);
|
||||
}
|
||||
static JSBool NativeInterface2JSObject(XPCLazyCallContext& lccx,
|
||||
jsval* d,
|
||||
@ -3260,7 +3277,6 @@ public:
|
||||
xpcObjectHelper& aHelper,
|
||||
const nsID* iid,
|
||||
XPCNativeInterface** Interface,
|
||||
JSObject* scope,
|
||||
PRBool allowNativeWrapper,
|
||||
PRBool isGlobal,
|
||||
nsresult* pErr);
|
||||
@ -3291,8 +3307,7 @@ public:
|
||||
static JSBool NativeArray2JS(XPCLazyCallContext& ccx,
|
||||
jsval* d, const void** s,
|
||||
const nsXPTType& type, const nsID* iid,
|
||||
JSUint32 count, JSObject* scope,
|
||||
nsresult* pErr);
|
||||
JSUint32 count, nsresult* pErr);
|
||||
|
||||
static JSBool JSArray2Native(XPCCallContext& ccx, void** d, jsval s,
|
||||
JSUint32 count, JSUint32 capacity,
|
||||
@ -4324,8 +4339,7 @@ public:
|
||||
*/
|
||||
static JSBool VariantDataToJS(XPCLazyCallContext& lccx,
|
||||
nsIVariant* variant,
|
||||
JSObject* scope, nsresult* pErr,
|
||||
jsval* pJSVal);
|
||||
nsresult* pErr, jsval* pJSVal);
|
||||
|
||||
protected:
|
||||
virtual ~XPCVariant() { }
|
||||
|
@ -869,6 +869,7 @@ castNative(JSContext *cx,
|
||||
}
|
||||
else if(cur)
|
||||
{
|
||||
NS_ABORT_IF_FALSE(IS_SLIM_WRAPPER(cur), "should be a slim wrapper");
|
||||
nsISupports *native = static_cast<nsISupports*>(xpc_GetJSPrivate(cur));
|
||||
if(NS_SUCCEEDED(getNative(native, GetOffsetsFromSlimWrapper(cur),
|
||||
cur, iid, ppThis, pThisRef, vp)))
|
||||
@ -1133,8 +1134,7 @@ xpc_qsXPCOMObjectToJsval(XPCLazyCallContext &lccx, qsObjectHelper &aHelper,
|
||||
nsresult rv;
|
||||
if(!XPCConvert::NativeInterface2JSObject(lccx, rval, nsnull,
|
||||
aHelper, iid, iface,
|
||||
lccx.GetCurrentJSObject(), PR_TRUE,
|
||||
OBJ_IS_NOT_GLOBAL, &rv))
|
||||
PR_TRUE, OBJ_IS_NOT_GLOBAL, &rv))
|
||||
{
|
||||
// I can't tell if NativeInterface2JSObject throws JS exceptions
|
||||
// or not. This is a sloppy stab at the right semantics; the
|
||||
@ -1164,9 +1164,7 @@ xpc_qsVariantToJsval(XPCLazyCallContext &lccx,
|
||||
if(p)
|
||||
{
|
||||
nsresult rv;
|
||||
JSBool ok = XPCVariant::VariantDataToJS(lccx, p,
|
||||
lccx.GetCurrentJSObject(),
|
||||
&rv, rval);
|
||||
JSBool ok = XPCVariant::VariantDataToJS(lccx, p, &rv, rval);
|
||||
if (!ok)
|
||||
xpc_qsThrow(lccx.GetJSContext(), rv);
|
||||
return ok;
|
||||
|
@ -412,8 +412,7 @@ XPCVariant::GetAsJSVal(jsval* result)
|
||||
JSBool
|
||||
XPCVariant::VariantDataToJS(XPCLazyCallContext& lccx,
|
||||
nsIVariant* variant,
|
||||
JSObject* scope, nsresult* pErr,
|
||||
jsval* pJSVal)
|
||||
nsresult* pErr, jsval* pJSVal)
|
||||
{
|
||||
// Get the type early because we might need to spoof it below.
|
||||
PRUint16 type;
|
||||
@ -429,11 +428,8 @@ XPCVariant::VariantDataToJS(XPCLazyCallContext& lccx,
|
||||
type == nsIDataType::VTYPE_EMPTY_ARRAY ||
|
||||
type == nsIDataType::VTYPE_ID))
|
||||
{
|
||||
// It's not a JSObject (or it's a JSArray or a JSObject representing an
|
||||
// nsID). Just pass through the underlying data.
|
||||
JSAutoEnterCompartment ac;
|
||||
JSContext *cx = lccx.GetJSContext();
|
||||
if(!ac.enter(cx, scope) || !JS_WrapValue(cx, &realVal))
|
||||
if(!JS_WrapValue(cx, &realVal))
|
||||
return JS_FALSE;
|
||||
*pJSVal = realVal;
|
||||
return JS_TRUE;
|
||||
@ -446,9 +442,8 @@ XPCVariant::VariantDataToJS(XPCLazyCallContext& lccx,
|
||||
type == nsIDataType::VTYPE_INTERFACE_IS,
|
||||
"Weird variant");
|
||||
|
||||
JSAutoEnterCompartment ac;
|
||||
JSContext *cx = lccx.GetJSContext();
|
||||
if(!ac.enter(cx, scope) || !JS_WrapValue(cx, &realVal))
|
||||
if(!JS_WrapValue(cx, &realVal))
|
||||
return JS_FALSE;
|
||||
*pJSVal = realVal;
|
||||
return JS_TRUE;
|
||||
@ -474,6 +469,9 @@ XPCVariant::VariantDataToJS(XPCLazyCallContext& lccx,
|
||||
JSBool success;
|
||||
|
||||
JSContext* cx = lccx.GetJSContext();
|
||||
NS_ABORT_IF_FALSE(lccx.GetScopeForNewJSObjects()->compartment() == cx->compartment,
|
||||
"bad scope for new JSObjects");
|
||||
|
||||
switch(type)
|
||||
{
|
||||
case nsIDataType::VTYPE_INT8:
|
||||
@ -656,8 +654,7 @@ XPCVariant::VariantDataToJS(XPCLazyCallContext& lccx,
|
||||
XPCConvert::NativeArray2JS(lccx, pJSVal,
|
||||
(const void**)&du.u.array.mArrayValue,
|
||||
conversionType, pid,
|
||||
du.u.array.mArrayCount,
|
||||
scope, pErr);
|
||||
du.u.array.mArrayCount, pErr);
|
||||
|
||||
VARIANT_DONE:
|
||||
nsVariant::Cleanup(&du);
|
||||
@ -697,7 +694,7 @@ VARIANT_DONE:
|
||||
success = XPCConvert::NativeData2JS(lccx, pJSVal,
|
||||
(const void*)&xpctvar.val,
|
||||
xpctvar.type,
|
||||
&iid, scope, pErr);
|
||||
&iid, pErr);
|
||||
}
|
||||
|
||||
if(xpctvar.IsValAllocated())
|
||||
|
@ -1309,20 +1309,26 @@ nsXPCWrappedJSClass::CallMethod(nsXPCWrappedJS* wrapper, uint16 methodIndex,
|
||||
cx = nsnull;
|
||||
}
|
||||
|
||||
if(!cx || !xpcc || !IsReflectable(methodIndex))
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
obj = thisObj = wrapper->GetJSObject();
|
||||
|
||||
JSAutoEnterCompartment ac;
|
||||
if (!ac.enter(cx, obj))
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
ccx.SetScopeForNewJSObjects(obj);
|
||||
|
||||
js::AutoValueVector args(cx);
|
||||
AutoScriptEvaluate scriptEval(cx);
|
||||
ContextPrincipalGuard principalGuard(ccx);
|
||||
|
||||
obj = thisObj = wrapper->GetJSObject();
|
||||
|
||||
// XXX ASSUMES that retval is last arg. The xpidl compiler ensures this.
|
||||
paramCount = info->num_args;
|
||||
argc = paramCount -
|
||||
(paramCount && XPT_PD_IS_RETVAL(info->params[paramCount-1].flags) ? 1 : 0);
|
||||
|
||||
if(!cx || !xpcc || !IsReflectable(methodIndex))
|
||||
goto pre_call_clean_up;
|
||||
|
||||
if (!scriptEval.StartEvaluating(obj, xpcWrappedJSErrorReporter))
|
||||
goto pre_call_clean_up;
|
||||
|
||||
@ -1440,7 +1446,7 @@ nsXPCWrappedJSClass::CallMethod(nsXPCWrappedJS* wrapper, uint16 methodIndex,
|
||||
JSBool ok =
|
||||
XPCConvert::NativeInterface2JSObject(ccx,
|
||||
&v, nsnull, helper, newWrapperIID,
|
||||
nsnull, obj, PR_FALSE, PR_FALSE,
|
||||
nsnull, PR_FALSE, PR_FALSE,
|
||||
nsnull);
|
||||
if(newWrapperIID)
|
||||
nsMemory::Free(newWrapperIID);
|
||||
@ -1477,41 +1483,6 @@ nsXPCWrappedJSClass::CallMethod(nsXPCWrappedJS* wrapper, uint16 methodIndex,
|
||||
argv = args.jsval_begin();
|
||||
sp = argv;
|
||||
|
||||
// Figure out what our callee is
|
||||
if(XPT_MD_IS_GETTER(info->flags) || XPT_MD_IS_SETTER(info->flags))
|
||||
{
|
||||
// Pull the getter or setter off of |obj|
|
||||
uintN attrs;
|
||||
JSBool found;
|
||||
JSPropertyOp getter;
|
||||
JSStrictPropertyOp setter;
|
||||
if(!JS_GetPropertyAttrsGetterAndSetter(cx, obj, name,
|
||||
&attrs, &found,
|
||||
&getter, &setter))
|
||||
{
|
||||
// XXX Do we want to report this exception?
|
||||
JS_ClearPendingException(cx);
|
||||
goto pre_call_clean_up;
|
||||
}
|
||||
|
||||
if(XPT_MD_IS_GETTER(info->flags) && (attrs & JSPROP_GETTER))
|
||||
{
|
||||
// JSPROP_GETTER means the getter is actually a
|
||||
// function object.
|
||||
ccx.SetCallee(JS_FUNC_TO_DATA_PTR(JSObject*, getter));
|
||||
}
|
||||
else if(XPT_MD_IS_SETTER(info->flags) && (attrs & JSPROP_SETTER))
|
||||
{
|
||||
// JSPROP_SETTER means the setter is actually a
|
||||
// function object.
|
||||
ccx.SetCallee(JS_FUNC_TO_DATA_PTR(JSObject*, setter));
|
||||
}
|
||||
}
|
||||
else if(JSVAL_IS_OBJECT(fval))
|
||||
{
|
||||
ccx.SetCallee(JSVAL_TO_OBJECT(fval));
|
||||
}
|
||||
|
||||
// build the args
|
||||
// NB: This assignment *looks* wrong because we haven't yet called our
|
||||
// function. However, we *have* already entered the compartmen that we're
|
||||
@ -1578,7 +1549,7 @@ nsXPCWrappedJSClass::CallMethod(nsXPCWrappedJS* wrapper, uint16 methodIndex,
|
||||
if(!XPCConvert::NativeArray2JS(lccx, &val,
|
||||
(const void**)&pv->val,
|
||||
datum_type, ¶m_iid,
|
||||
array_count, obj, nsnull))
|
||||
array_count, nsnull))
|
||||
goto pre_call_clean_up;
|
||||
}
|
||||
else if(isSizedString)
|
||||
@ -1592,7 +1563,7 @@ nsXPCWrappedJSClass::CallMethod(nsXPCWrappedJS* wrapper, uint16 methodIndex,
|
||||
else
|
||||
{
|
||||
if(!XPCConvert::NativeData2JS(ccx, &val, &pv->val, type,
|
||||
¶m_iid, obj, nsnull))
|
||||
¶m_iid, nsnull))
|
||||
goto pre_call_clean_up;
|
||||
}
|
||||
}
|
||||
|
@ -2595,8 +2595,7 @@ CallMethodHelper::GatherAndConvertResults()
|
||||
XPCLazyCallContext lccx(mCallContext);
|
||||
if(!XPCConvert::NativeArray2JS(lccx, &v, (const void**)&dp->val,
|
||||
datum_type, ¶m_iid,
|
||||
array_count, mCallContext.GetCurrentJSObject(),
|
||||
&err))
|
||||
array_count, &err))
|
||||
{
|
||||
// XXX need exception scheme for arrays to indicate bad element
|
||||
ThrowBadParam(err, i, mCallContext);
|
||||
@ -2617,8 +2616,7 @@ CallMethodHelper::GatherAndConvertResults()
|
||||
else
|
||||
{
|
||||
if(!XPCConvert::NativeData2JS(mCallContext, &v, &dp->val, datum_type,
|
||||
¶m_iid,
|
||||
mCallContext.GetCurrentJSObject(), &err))
|
||||
¶m_iid, &err))
|
||||
{
|
||||
ThrowBadParam(err, i, mCallContext);
|
||||
return JS_FALSE;
|
||||
@ -2703,7 +2701,7 @@ CallMethodHelper::QueryInterfaceFastPath() const
|
||||
JSBool success =
|
||||
XPCConvert::NativeData2JS(mCallContext, &v, &qiresult,
|
||||
nsXPTType::T_INTERFACE_IS | XPT_TDP_POINTER,
|
||||
iid, mCallContext.GetCurrentJSObject(), &err);
|
||||
iid, &err);
|
||||
NS_IF_RELEASE(qiresult);
|
||||
|
||||
if(!success)
|
||||
|
@ -135,7 +135,7 @@ XPCNativeMember::Resolve(XPCCallContext& ccx, XPCNativeInterface* iface,
|
||||
jsval resultVal;
|
||||
|
||||
if(!XPCConvert::NativeData2JS(ccx, &resultVal, &v.val, v.type,
|
||||
nsnull, nsnull, nsnull))
|
||||
nsnull, nsnull))
|
||||
return JS_FALSE;
|
||||
|
||||
*vp = resultVal;
|
||||
|
@ -1690,6 +1690,7 @@ XPC_WN_Shared_Proto_Enumerate(JSContext *cx, JSObject *obj)
|
||||
XPCCallContext ccx(JS_CALLER, cx);
|
||||
if(!ccx.IsValid())
|
||||
return JS_FALSE;
|
||||
ccx.SetScopeForNewJSObjects(obj);
|
||||
|
||||
PRUint16 interface_count = set->GetInterfaceCount();
|
||||
XPCNativeInterface** interfaceArray = set->GetInterfaceArray();
|
||||
@ -1752,6 +1753,7 @@ XPC_WN_ModsAllowed_Proto_Resolve(JSContext *cx, JSObject *obj, jsid id)
|
||||
XPCCallContext ccx(JS_CALLER, cx);
|
||||
if(!ccx.IsValid())
|
||||
return JS_FALSE;
|
||||
ccx.SetScopeForNewJSObjects(obj);
|
||||
|
||||
XPCNativeScriptableInfo* si = self->GetScriptableInfo();
|
||||
uintN enumFlag = (si && si->GetFlags().DontEnumStaticProps()) ?
|
||||
@ -1835,6 +1837,7 @@ XPC_WN_OnlyIWrite_Proto_AddPropertyStub(JSContext *cx, JSObject *obj, jsid id, j
|
||||
XPCCallContext ccx(JS_CALLER, cx);
|
||||
if(!ccx.IsValid())
|
||||
return JS_FALSE;
|
||||
ccx.SetScopeForNewJSObjects(obj);
|
||||
|
||||
// Allow XPConnect to add the property only
|
||||
if(ccx.GetResolveName() == id)
|
||||
@ -1865,6 +1868,7 @@ XPC_WN_NoMods_Proto_Resolve(JSContext *cx, JSObject *obj, jsid id)
|
||||
XPCCallContext ccx(JS_CALLER, cx);
|
||||
if(!ccx.IsValid())
|
||||
return JS_FALSE;
|
||||
ccx.SetScopeForNewJSObjects(obj);
|
||||
|
||||
XPCNativeScriptableInfo* si = self->GetScriptableInfo();
|
||||
uintN enumFlag = (si && si->GetFlags().DontEnumStaticProps()) ?
|
||||
|
@ -184,26 +184,31 @@ WrapperFactory::PrepareForWrapping(JSContext *cx, JSObject *scope, JSObject *obj
|
||||
if (!wn->GetClassInfo())
|
||||
return DoubleWrap(cx, obj, flags);
|
||||
|
||||
XPCCallContext ccx(JS_CALLER, cx, obj);
|
||||
if (NATIVE_HAS_FLAG(&ccx, WantPreCreate)) {
|
||||
// We have a precreate hook. This object might enforce that we only
|
||||
// ever create JS object for it.
|
||||
JSObject *originalScope = scope;
|
||||
nsresult rv = wn->GetScriptableInfo()->GetCallback()->
|
||||
PreCreate(wn->Native(), cx, scope, &scope);
|
||||
NS_ENSURE_SUCCESS(rv, DoubleWrap(cx, obj, flags));
|
||||
{
|
||||
JSAutoEnterCompartment ac;
|
||||
if (!ac.enter(cx, obj))
|
||||
return nsnull;
|
||||
XPCCallContext ccx(JS_CALLER, cx, obj);
|
||||
if (NATIVE_HAS_FLAG(&ccx, WantPreCreate)) {
|
||||
// We have a precreate hook. This object might enforce that we only
|
||||
// ever create JS object for it.
|
||||
JSObject *originalScope = scope;
|
||||
nsresult rv = wn->GetScriptableInfo()->GetCallback()->
|
||||
PreCreate(wn->Native(), cx, scope, &scope);
|
||||
NS_ENSURE_SUCCESS(rv, DoubleWrap(cx, obj, flags));
|
||||
|
||||
// If the handed back scope differs from the passed-in scope and is in
|
||||
// a separate compartment, then this object is explicitly requesting
|
||||
// that we don't create a second JS object for it: create a security
|
||||
// wrapper.
|
||||
if (originalScope->compartment() != scope->getCompartment())
|
||||
return DoubleWrap(cx, obj, flags);
|
||||
// If the handed back scope differs from the passed-in scope and is in
|
||||
// a separate compartment, then this object is explicitly requesting
|
||||
// that we don't create a second JS object for it: create a security
|
||||
// wrapper.
|
||||
if (originalScope->compartment() != scope->getCompartment())
|
||||
return DoubleWrap(cx, obj, flags);
|
||||
|
||||
// Note: this penalizes objects that only have one wrapper, but are
|
||||
// being accessed across compartments. We would really prefer to
|
||||
// replace the above code with a test that says "do you only have one
|
||||
// wrapper?"
|
||||
// Note: this penalizes objects that only have one wrapper, but are
|
||||
// being accessed across compartments. We would really prefer to
|
||||
// replace the above code with a test that says "do you only have one
|
||||
// wrapper?"
|
||||
}
|
||||
}
|
||||
|
||||
// The object we're looking at might allow us to create a new wrapped
|
||||
|
Loading…
Reference in New Issue
Block a user