зеркало из https://github.com/mozilla/pjs.git
Bug 514081 - Don't overload the parent slot in SJOWs. r=jst
This commit is contained in:
Родитель
4df7c0116b
Коммит
bd2b55e183
|
@ -251,8 +251,10 @@ RewrapIfDeepWrapper(JSContext *cx, JSObject *obj, jsval v, jsval *rval)
|
|||
|
||||
XPCWrappedNative* wrappedNative =
|
||||
XPCWrappedNative::GetAndMorphWrappedNativeOfJSObject(cx, nativeObj);
|
||||
if (!wrappedNative)
|
||||
return XPCSafeJSObjectWrapper::WrapObject(cx, nsnull, v, rval);
|
||||
if (!wrappedNative) {
|
||||
return XPCSafeJSObjectWrapper::WrapObject(cx, JS_GetScopeChain(cx),
|
||||
v, rval);
|
||||
}
|
||||
|
||||
if (HAS_FLAGS(flags, FLAG_EXPLICIT)) {
|
||||
#ifdef DEBUG_XPCNativeWrapper
|
||||
|
@ -278,6 +280,7 @@ RewrapIfDeepWrapper(JSContext *cx, JSObject *obj, jsval v, jsval *rval)
|
|||
// GetWrappedNativeOfJSObject will give the right thing -- the unique deep
|
||||
// implicit wrapper associated with wrappedNative.
|
||||
JSObject* wrapperObj = XPCNativeWrapper::GetNewOrUsed(cx, wrappedNative,
|
||||
JS_GetScopeChain(cx),
|
||||
nsnull);
|
||||
if (!wrapperObj) {
|
||||
return JS_FALSE;
|
||||
|
@ -912,7 +915,8 @@ MirrorWrappedNativeParent(JSContext *cx, XPCWrappedNative *wrapper,
|
|||
// scope. In that case, the best we can do is just use the
|
||||
// non-native-wrapped sandbox global object for our parent.
|
||||
if (parent_wrapper) {
|
||||
*result = XPCNativeWrapper::GetNewOrUsed(cx, parent_wrapper, nsnull);
|
||||
*result = XPCNativeWrapper::GetNewOrUsed(cx, parent_wrapper, nsnull,
|
||||
nsnull);
|
||||
if (!*result)
|
||||
return JS_FALSE;
|
||||
} else {
|
||||
|
@ -1230,7 +1234,7 @@ XPCNativeWrapper::AttachNewConstructorObject(XPCCallContext &ccx,
|
|||
// static
|
||||
JSObject *
|
||||
XPCNativeWrapper::GetNewOrUsed(JSContext *cx, XPCWrappedNative *wrapper,
|
||||
nsIPrincipal *aObjectPrincipal)
|
||||
JSObject *scope, nsIPrincipal *aObjectPrincipal)
|
||||
{
|
||||
if (aObjectPrincipal) {
|
||||
nsIScriptSecurityManager *ssm = GetSecurityManager();
|
||||
|
@ -1259,7 +1263,7 @@ XPCNativeWrapper::GetNewOrUsed(JSContext *cx, XPCWrappedNative *wrapper,
|
|||
// Make sure v doesn't get collected while we're re-wrapping it.
|
||||
AUTO_MARK_JSVAL(ccx, v);
|
||||
|
||||
if (XPCSafeJSObjectWrapper::WrapObject(cx, nsnull, v, &v))
|
||||
if (XPCSafeJSObjectWrapper::WrapObject(cx, scope, v, &v))
|
||||
return JSVAL_TO_OBJECT(v);
|
||||
|
||||
return nsnull;
|
||||
|
|
|
@ -51,7 +51,7 @@ AttachNewConstructorObject(XPCCallContext &ccx, JSObject *aGlobalObject);
|
|||
|
||||
JSObject *
|
||||
GetNewOrUsed(JSContext *cx, XPCWrappedNative *wrapper,
|
||||
nsIPrincipal *aObjectPrincipal);
|
||||
JSObject *scope, nsIPrincipal *aObjectPrincipal);
|
||||
JSBool
|
||||
CreateExplicitWrapper(JSContext *cx, XPCWrappedNative *wrapper, JSBool deep,
|
||||
jsval *rval);
|
||||
|
|
|
@ -286,11 +286,6 @@ AttachNewConstructorObject(XPCCallContext &ccx, JSObject *aGlobalObject)
|
|||
return PR_FALSE;
|
||||
}
|
||||
|
||||
// Null out the class object's parent to prevent code in this class
|
||||
// from thinking the class object is a wrapper for the global
|
||||
// object.
|
||||
::JS_SetParent(ccx, class_obj, nsnull);
|
||||
|
||||
// Make sure our prototype chain is empty and that people can't mess
|
||||
// with XPCSafeJSObjectWrapper.prototype.
|
||||
::JS_SetPrototype(ccx, class_obj, nsnull);
|
||||
|
@ -307,7 +302,7 @@ AttachNewConstructorObject(XPCCallContext &ccx, JSObject *aGlobalObject)
|
|||
}
|
||||
|
||||
JSObject *
|
||||
GetUnsafeObject(JSObject *obj)
|
||||
GetUnsafeObject(JSContext *cx, JSObject *obj)
|
||||
{
|
||||
obj = FindSafeObject(obj);
|
||||
|
||||
|
@ -315,7 +310,13 @@ GetUnsafeObject(JSObject *obj)
|
|||
return nsnull;
|
||||
}
|
||||
|
||||
return STOBJ_GET_PARENT(obj);
|
||||
jsval v;
|
||||
if (!JS_GetReservedSlot(cx, obj, XPCWrapper::sWrappedObjSlot, &v)) {
|
||||
JS_ClearPendingException(cx);
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
return JSVAL_IS_OBJECT(v) ? JSVAL_TO_OBJECT(v) : nsnull;
|
||||
}
|
||||
|
||||
} // namespace XPCSafeJSObjectWrapper
|
||||
|
@ -408,13 +409,13 @@ WrapJSValue(JSContext *cx, JSObject *obj, jsval val, jsval *rval)
|
|||
}
|
||||
|
||||
static jsval
|
||||
UnwrapJSValue(jsval val)
|
||||
UnwrapJSValue(JSContext *cx, jsval val)
|
||||
{
|
||||
if (JSVAL_IS_PRIMITIVE(val)) {
|
||||
return val;
|
||||
}
|
||||
|
||||
JSObject *unsafeObj = GetUnsafeObject(JSVAL_TO_OBJECT(val));
|
||||
JSObject *unsafeObj = GetUnsafeObject(cx, JSVAL_TO_OBJECT(val));
|
||||
if (unsafeObj) {
|
||||
return OBJECT_TO_JSVAL(unsafeObj);
|
||||
}
|
||||
|
@ -443,7 +444,7 @@ XPC_SJOW_AddProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
|
|||
return ok;
|
||||
}
|
||||
|
||||
JSObject *unsafeObj = GetUnsafeObject(obj);
|
||||
JSObject *unsafeObj = GetUnsafeObject(cx, obj);
|
||||
if (!unsafeObj) {
|
||||
return ThrowException(NS_ERROR_UNEXPECTED, cx);
|
||||
}
|
||||
|
@ -460,7 +461,7 @@ XPC_SJOW_AddProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
|
|||
static JSBool
|
||||
XPC_SJOW_DelProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
|
||||
{
|
||||
JSObject *unsafeObj = GetUnsafeObject(obj);
|
||||
JSObject *unsafeObj = GetUnsafeObject(cx, obj);
|
||||
if (!unsafeObj) {
|
||||
return ThrowException(NS_ERROR_UNEXPECTED, cx);
|
||||
}
|
||||
|
@ -533,7 +534,7 @@ XPC_SJOW_GetOrSetProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp,
|
|||
obj = FindSafeObject(obj);
|
||||
NS_ASSERTION(obj != nsnull, "FindSafeObject() returned null in class hook!");
|
||||
|
||||
JSObject *unsafeObj = GetUnsafeObject(obj);
|
||||
JSObject *unsafeObj = GetUnsafeObject(cx, obj);
|
||||
if (!unsafeObj) {
|
||||
return ThrowException(NS_ERROR_UNEXPECTED, cx);
|
||||
}
|
||||
|
@ -556,7 +557,7 @@ XPC_SJOW_GetOrSetProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp,
|
|||
}
|
||||
|
||||
if (aIsSet) {
|
||||
*vp = UnwrapJSValue(*vp);
|
||||
*vp = UnwrapJSValue(cx, *vp);
|
||||
}
|
||||
|
||||
JSBool ok = aIsSet
|
||||
|
@ -595,7 +596,7 @@ XPC_SJOW_Enumerate(JSContext *cx, JSObject *obj)
|
|||
// enumerated identifiers from the unsafe object to the safe
|
||||
// wrapper.
|
||||
|
||||
JSObject *unsafeObj = GetUnsafeObject(obj);
|
||||
JSObject *unsafeObj = GetUnsafeObject(cx, obj);
|
||||
if (!unsafeObj) {
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
@ -621,7 +622,7 @@ XPC_SJOW_NewResolve(JSContext *cx, JSObject *obj, jsval id, uintN flags,
|
|||
obj = FindSafeObject(obj);
|
||||
NS_ASSERTION(obj != nsnull, "FindSafeObject() returned null in class hook!");
|
||||
|
||||
JSObject *unsafeObj = GetUnsafeObject(obj);
|
||||
JSObject *unsafeObj = GetUnsafeObject(cx, obj);
|
||||
if (!unsafeObj) {
|
||||
// No unsafe object, nothing to resolve here.
|
||||
|
||||
|
@ -679,7 +680,7 @@ XPC_SJOW_CheckAccess(JSContext *cx, JSObject *obj, jsval id,
|
|||
return JS_FALSE;
|
||||
}
|
||||
|
||||
JSObject *unsafeObj = GetUnsafeObject(obj);
|
||||
JSObject *unsafeObj = GetUnsafeObject(cx, obj);
|
||||
if (!unsafeObj) {
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
@ -732,7 +733,7 @@ XPC_SJOW_Call(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
|
|||
}
|
||||
}
|
||||
|
||||
unsafeObj = GetUnsafeObject(obj);
|
||||
unsafeObj = GetUnsafeObject(cx, obj);
|
||||
if (!unsafeObj) {
|
||||
return ThrowException(NS_ERROR_UNEXPECTED, cx);
|
||||
}
|
||||
|
@ -742,7 +743,7 @@ XPC_SJOW_Call(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
|
|||
}
|
||||
|
||||
JSObject *safeObj = JSVAL_TO_OBJECT(argv[-2]);
|
||||
JSObject *funToCall = GetUnsafeObject(safeObj);
|
||||
JSObject *funToCall = GetUnsafeObject(cx, safeObj);
|
||||
|
||||
if (!funToCall) {
|
||||
// Someone has called XPCSafeJSObjectWrapper.prototype() causing
|
||||
|
@ -762,7 +763,7 @@ XPC_SJOW_Call(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
|
|||
SafeCallGuard guard(cx, FindObjectPrincipals(cx, safeObj, funToCall));
|
||||
|
||||
for (uintN i = 0; i < argc; ++i) {
|
||||
argv[i] = UnwrapJSValue(argv[i]);
|
||||
argv[i] = UnwrapJSValue(cx, argv[i]);
|
||||
}
|
||||
|
||||
if (!JS_CallFunctionValue(cx, callThisObj, OBJECT_TO_JSVAL(funToCall),
|
||||
|
@ -782,9 +783,10 @@ XPC_SJOW_Construct(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
|
|||
return ThrowException(NS_ERROR_XPC_NOT_ENOUGH_ARGS, cx);
|
||||
}
|
||||
|
||||
// |obj| almost always has the wrong proto and parent so we have to create
|
||||
// our own object anyway. Set |obj| to null so we don't use it by accident.
|
||||
obj = nsnull;
|
||||
// We're not going to use obj because we have callers who aren't the JS
|
||||
// engine, but we can use it to figure out what scope we're creating this
|
||||
// SJOW for.
|
||||
JSObject *scope = JS_GetGlobalForObject(cx, obj);
|
||||
|
||||
if (JSVAL_IS_PRIMITIVE(argv[0])) {
|
||||
JSStackFrame *fp = nsnull;
|
||||
|
@ -810,7 +812,7 @@ XPC_SJOW_Construct(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
|
|||
}
|
||||
|
||||
SLIM_LOG_WILL_MORPH(cx, objToWrap);
|
||||
if(IS_SLIM_WRAPPER(objToWrap) && !MorphSlimWrapper(cx, objToWrap)) {
|
||||
if (IS_SLIM_WRAPPER(objToWrap) && !MorphSlimWrapper(cx, objToWrap)) {
|
||||
return ThrowException(NS_ERROR_FAILURE, cx);
|
||||
}
|
||||
|
||||
|
@ -820,7 +822,7 @@ XPC_SJOW_Construct(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
|
|||
return JS_FALSE;
|
||||
}
|
||||
|
||||
JSObject *unsafeObj = GetUnsafeObject(objToWrap);
|
||||
JSObject *unsafeObj = GetUnsafeObject(cx, objToWrap);
|
||||
|
||||
if (unsafeObj) {
|
||||
// We're asked to wrap an already wrapped object. Re-wrap the
|
||||
|
@ -829,23 +831,21 @@ XPC_SJOW_Construct(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
|
|||
objToWrap = unsafeObj;
|
||||
}
|
||||
|
||||
// Don't use the object the JS engine created for us, it is in most
|
||||
// cases incorectly parented and has a proto from the wrong scope.
|
||||
JSObject *wrapperObj =
|
||||
::JS_NewObjectWithGivenProto(cx, &SJOWClass.base, nsnull,
|
||||
objToWrap);
|
||||
JS_NewObjectWithGivenProto(cx, &SJOWClass.base, nsnull, scope);
|
||||
|
||||
if (!wrapperObj) {
|
||||
// JS_NewObjectWithGivenProto already threw.
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
if (!::JS_SetReservedSlot(cx, wrapperObj, sFlagsSlot, JSVAL_ZERO)) {
|
||||
*rval = OBJECT_TO_JSVAL(wrapperObj);
|
||||
if (!JS_SetReservedSlot(cx, wrapperObj, XPCWrapper::sWrappedObjSlot,
|
||||
OBJECT_TO_JSVAL(objToWrap)) ||
|
||||
!JS_SetReservedSlot(cx, wrapperObj, XPCWrapper::sFlagsSlot, JSVAL_ZERO)) {
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
*rval = OBJECT_TO_JSVAL(wrapperObj);
|
||||
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
|
@ -854,8 +854,8 @@ XPC_SJOW_Create(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
|
|||
jsval *rval)
|
||||
{
|
||||
JSObject *callee = JSVAL_TO_OBJECT(argv[-2]);
|
||||
NS_ASSERTION(GetUnsafeObject(callee), "How'd we get here?");
|
||||
JSObject *unsafeObj = GetUnsafeObject(callee);
|
||||
NS_ASSERTION(GetUnsafeObject(cx, callee), "How'd we get here?");
|
||||
JSObject *unsafeObj = GetUnsafeObject(cx, callee);
|
||||
|
||||
// Check that the caller can access the unsafe object.
|
||||
if (!CanCallerAccess(cx, unsafeObj)) {
|
||||
|
@ -884,10 +884,10 @@ XPC_SJOW_Equality(JSContext *cx, JSObject *obj, jsval v, JSBool *bp)
|
|||
if (JSVAL_IS_PRIMITIVE(v)) {
|
||||
*bp = JS_FALSE;
|
||||
} else {
|
||||
JSObject *unsafeObj = GetUnsafeObject(obj);
|
||||
JSObject *unsafeObj = GetUnsafeObject(cx, obj);
|
||||
|
||||
JSObject *other = JSVAL_TO_OBJECT(v);
|
||||
JSObject *otherUnsafe = GetUnsafeObject(other);
|
||||
JSObject *otherUnsafe = GetUnsafeObject(cx, other);
|
||||
|
||||
// An object is equal to a SJOW if:
|
||||
// - The other object is the same SJOW.
|
||||
|
@ -915,7 +915,7 @@ XPC_SJOW_Iterator(JSContext *cx, JSObject *obj, JSBool keysonly)
|
|||
obj = FindSafeObject(obj);
|
||||
NS_ASSERTION(obj != nsnull, "FindSafeObject() returned null in class hook!");
|
||||
|
||||
JSObject *unsafeObj = GetUnsafeObject(obj);
|
||||
JSObject *unsafeObj = GetUnsafeObject(cx, obj);
|
||||
if (!unsafeObj) {
|
||||
ThrowException(NS_ERROR_INVALID_ARG, cx);
|
||||
|
||||
|
@ -944,13 +944,16 @@ XPC_SJOW_Iterator(JSContext *cx, JSObject *obj, JSBool keysonly)
|
|||
|
||||
// Create our dummy SJOW.
|
||||
JSObject *wrapperIter =
|
||||
::JS_NewObjectWithGivenProto(cx, &SJOWClass.base, nsnull,
|
||||
unsafeObj);
|
||||
JS_NewObjectWithGivenProto(cx, &SJOWClass.base, nsnull,
|
||||
JS_GetGlobalForObject(cx, obj));
|
||||
if (!wrapperIter) {
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
if (!::JS_SetReservedSlot(cx, wrapperIter, sFlagsSlot, JSVAL_ZERO)) {
|
||||
if (!JS_SetReservedSlot(cx, wrapperIter, XPCWrapper::sWrappedObjSlot,
|
||||
OBJECT_TO_JSVAL(unsafeObj)) ||
|
||||
!JS_SetReservedSlot(cx, wrapperIter, XPCWrapper::sFlagsSlot,
|
||||
JSVAL_ZERO)) {
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
|
@ -964,7 +967,7 @@ XPC_SJOW_Iterator(JSContext *cx, JSObject *obj, JSBool keysonly)
|
|||
static JSObject *
|
||||
XPC_SJOW_WrappedObject(JSContext *cx, JSObject *obj)
|
||||
{
|
||||
return GetUnsafeObject(obj);
|
||||
return GetUnsafeObject(cx, obj);
|
||||
}
|
||||
|
||||
static JSBool
|
||||
|
@ -976,7 +979,7 @@ XPC_SJOW_toString(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
|
|||
return ThrowException(NS_ERROR_INVALID_ARG, cx);
|
||||
}
|
||||
|
||||
JSObject *unsafeObj = GetUnsafeObject(obj);
|
||||
JSObject *unsafeObj = GetUnsafeObject(cx, obj);
|
||||
|
||||
if (!unsafeObj) {
|
||||
// No unsafe object, nothing to stringify here, return "[object
|
||||
|
|
|
@ -75,7 +75,8 @@ Unwrap(JSContext *cx, JSObject *wrapper)
|
|||
}
|
||||
|
||||
if (clasp == &XPCSafeJSObjectWrapper::SJOWClass.base) {
|
||||
JSObject *wrappedObj = STOBJ_GET_PARENT(wrapper);
|
||||
JSObject *wrappedObj =
|
||||
XPCSafeJSObjectWrapper::GetUnsafeObject(cx, wrapper);
|
||||
|
||||
if (NS_FAILED(XPCCrossOriginWrapper::CanAccessWrapper(cx, wrappedObj, nsnull))) {
|
||||
JS_ClearPendingException(cx);
|
||||
|
|
|
@ -131,7 +131,7 @@ WrapObject(JSContext *cx, JSObject *parent, jsval v, jsval *vp);
|
|||
namespace XPCSafeJSObjectWrapper {
|
||||
|
||||
JSObject *
|
||||
GetUnsafeObject(JSObject *obj);
|
||||
GetUnsafeObject(JSContext *cx, JSObject *obj);
|
||||
|
||||
JSBool
|
||||
WrapObject(JSContext *cx, JSObject *scope, jsval v, jsval *vp);
|
||||
|
|
|
@ -2569,12 +2569,12 @@ nsXPConnect::GetWrapperForObject(JSContext* aJSContext,
|
|||
}
|
||||
|
||||
wrappedObj = XPCNativeWrapper::GetNewOrUsed(aJSContext, wrapper,
|
||||
aPrincipal);
|
||||
aScope, aPrincipal);
|
||||
}
|
||||
else if(aFilenameFlags & JSFILENAME_SYSTEM)
|
||||
{
|
||||
jsval val = OBJECT_TO_JSVAL(aObject);
|
||||
if(XPCSafeJSObjectWrapper::WrapObject(aJSContext, nsnull, val, &val))
|
||||
if(XPCSafeJSObjectWrapper::WrapObject(aJSContext, aScope, val, &val))
|
||||
wrappedObj = JSVAL_TO_OBJECT(val);
|
||||
}
|
||||
else
|
||||
|
|
|
@ -1352,7 +1352,7 @@ XPCConvert::NativeInterface2JSObject(XPCLazyCallContext& lccx,
|
|||
|
||||
destObj =
|
||||
XPCNativeWrapper::GetNewOrUsed(ccx, wrapper,
|
||||
objPrincipal);
|
||||
scope, objPrincipal);
|
||||
triedWrapping = JS_TRUE;
|
||||
}
|
||||
else if (flags & JSFILENAME_SYSTEM)
|
||||
|
@ -1362,7 +1362,7 @@ XPCConvert::NativeInterface2JSObject(XPCLazyCallContext& lccx,
|
|||
"XPCSafeJSObjectWrapper\n");
|
||||
#endif
|
||||
|
||||
if(XPCSafeJSObjectWrapper::WrapObject(ccx, nsnull, v, &v))
|
||||
if(XPCSafeJSObjectWrapper::WrapObject(ccx, scope, v, &v))
|
||||
destObj = JSVAL_TO_OBJECT(v);
|
||||
triedWrapping = JS_TRUE;
|
||||
}
|
||||
|
|
|
@ -818,7 +818,7 @@ XPC_GetIdentityObject(JSContext *cx, JSObject *obj)
|
|||
wrapper = XPCWrappedNative::GetWrappedNativeOfJSObject(cx, obj);
|
||||
|
||||
if(!wrapper) {
|
||||
JSObject *unsafeObj = XPCSafeJSObjectWrapper::GetUnsafeObject(obj);
|
||||
JSObject *unsafeObj = XPCSafeJSObjectWrapper::GetUnsafeObject(cx, obj);
|
||||
if(unsafeObj)
|
||||
return XPC_GetIdentityObject(cx, unsafeObj);
|
||||
|
||||
|
@ -855,7 +855,7 @@ XPC_WN_Equality(JSContext *cx, JSObject *obj, jsval v, JSBool *bp)
|
|||
if(!*bp && !JSVAL_IS_PRIMITIVE(v) &&
|
||||
STOBJ_GET_CLASS(JSVAL_TO_OBJECT(v)) == &XPCSafeJSObjectWrapper::SJOWClass.base)
|
||||
{
|
||||
v = OBJECT_TO_JSVAL(XPCSafeJSObjectWrapper::GetUnsafeObject(JSVAL_TO_OBJECT(v)));
|
||||
v = OBJECT_TO_JSVAL(XPCSafeJSObjectWrapper::GetUnsafeObject(cx, JSVAL_TO_OBJECT(v)));
|
||||
|
||||
rv = si->GetCallback()->Equality(wrapper, cx, obj, v, bp);
|
||||
if(NS_FAILED(rv))
|
||||
|
|
Загрузка…
Ссылка в новой задаче