Bug 533882 - Don't call into CAPs when we don't have to. r=jst sr=bzbarsky

--HG--
extra : rebase_source : 534bfae23aa5c1de4229b5259ba48599aef69a12
This commit is contained in:
Blake Kaplan 2009-12-16 17:40:14 -08:00
Родитель a0ccb694f5
Коммит dba00a57db
3 изменённых файлов: 52 добавлений и 22 удалений

Просмотреть файл

@ -221,8 +221,35 @@ WrapperMoved(JSContext *cx, XPCWrappedNative *innerObj,
// returns NS_ERROR_DOM_PROP_ACCESS_DENIED, returns another error code on
// failure.
nsresult
CanAccessWrapper(JSContext *cx, JSObject *wrappedObj, JSBool *privilegeEnabled)
CanAccessWrapper(JSContext *cx, JSObject *outerObj, JSObject *wrappedObj,
JSBool *privilegeEnabled)
{
// Fast path: If the wrapper and the wrapped object have the same global
// object (or if the wrapped object is a outer for the same inner that
// the wrapper is parented to), then we don't need to do any more work.
if (privilegeEnabled) {
*privilegeEnabled = JS_FALSE;
}
if (outerObj) {
JSObject *outerParent = outerObj->getParent();
JSObject *innerParent = wrappedObj->getParent();
if (!innerParent) {
innerParent = wrappedObj;
OBJ_TO_INNER_OBJECT(cx, innerParent);
if (!innerParent) {
return NS_ERROR_FAILURE;
}
} else {
innerParent = JS_GetGlobalForObject(cx, innerParent);
}
if (outerParent == innerParent) {
return NS_OK;
}
}
// TODO bug 508928: Refactor this with the XOW security checking code.
// Get the subject principal from the execution stack.
nsIScriptSecurityManager *ssm = XPCWrapper::GetSecurityManager();
@ -473,7 +500,7 @@ XPC_XOW_FunctionWrapper(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
// 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);
outerObj = wrappedObj = GetWrapper(obj);
if (wrappedObj) {
wrappedObj = GetWrappedObject(cx, wrappedObj);
if (!wrappedObj) {
@ -499,7 +526,7 @@ XPC_XOW_FunctionWrapper(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
return ThrowException(NS_ERROR_FAILURE, cx);
}
nsresult rv = CanAccessWrapper(cx, JSVAL_TO_OBJECT(funToCall), nsnull);
nsresult rv = CanAccessWrapper(cx, outerObj, JSVAL_TO_OBJECT(funToCall), nsnull);
if (NS_FAILED(rv) && rv != NS_ERROR_DOM_PROP_ACCESS_DENIED) {
return ThrowException(rv, cx);
}
@ -585,7 +612,7 @@ XPC_XOW_AddProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
}
JSBool privilegeEnabled = JS_FALSE;
nsresult rv = CanAccessWrapper(cx, wrappedObj, &privilegeEnabled);
nsresult rv = CanAccessWrapper(cx, obj, wrappedObj, &privilegeEnabled);
if (NS_FAILED(rv)) {
if (rv == NS_ERROR_DOM_PROP_ACCESS_DENIED) {
// Can't override properties on foreign objects.
@ -611,7 +638,7 @@ XPC_XOW_DelProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
return ThrowException(NS_ERROR_FAILURE, cx);
}
nsresult rv = CanAccessWrapper(cx, wrappedObj, nsnull);
nsresult rv = CanAccessWrapper(cx, obj, wrappedObj, nsnull);
if (NS_FAILED(rv)) {
if (rv == NS_ERROR_DOM_PROP_ACCESS_DENIED) {
// Can't delete properties on foreign objects.
@ -662,7 +689,7 @@ XPC_XOW_GetOrSetProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp,
}
JSBool privilegeEnabled;
nsresult rv = CanAccessWrapper(cx, wrappedObj, &privilegeEnabled);
nsresult rv = CanAccessWrapper(cx, obj, wrappedObj, &privilegeEnabled);
if (NS_FAILED(rv)) {
if (rv != NS_ERROR_DOM_PROP_ACCESS_DENIED) {
return JS_FALSE;
@ -774,7 +801,7 @@ XPC_XOW_Enumerate(JSContext *cx, JSObject *obj)
return ThrowException(NS_ERROR_FAILURE, cx);
}
nsresult rv = CanAccessWrapper(cx, wrappedObj, nsnull);
nsresult rv = CanAccessWrapper(cx, obj, wrappedObj, nsnull);
if (NS_FAILED(rv)) {
if (rv == NS_ERROR_DOM_PROP_ACCESS_DENIED) {
// Can't enumerate on foreign objects.
@ -871,7 +898,7 @@ XPC_XOW_NewResolve(JSContext *cx, JSObject *obj, jsval id, uintN flags,
}
JSBool privilegeEnabled;
nsresult rv = CanAccessWrapper(cx, wrappedObj, &privilegeEnabled);
nsresult rv = CanAccessWrapper(cx, obj, wrappedObj, &privilegeEnabled);
if (NS_FAILED(rv)) {
if (rv != NS_ERROR_DOM_PROP_ACCESS_DENIED) {
return JS_FALSE;
@ -964,7 +991,7 @@ XPC_XOW_Convert(JSContext *cx, JSObject *obj, JSType type, jsval *vp)
}
// Note: JSTYPE_VOID and JSTYPE_STRING are equivalent.
nsresult rv = CanAccessWrapper(cx, wrappedObj, nsnull);
nsresult rv = CanAccessWrapper(cx, obj, wrappedObj, nsnull);
if (NS_FAILED(rv) &&
(rv != NS_ERROR_DOM_PROP_ACCESS_DENIED ||
(type != JSTYPE_STRING && type != JSTYPE_VOID))) {
@ -1038,7 +1065,7 @@ XPC_XOW_Call(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
return ThrowException(NS_ERROR_FAILURE, cx);
}
nsresult rv = CanAccessWrapper(cx, wrappedObj, nsnull);
nsresult rv = CanAccessWrapper(cx, obj, wrappedObj, nsnull);
if (NS_FAILED(rv)) {
if (rv == NS_ERROR_DOM_PROP_ACCESS_DENIED) {
// Can't call.
@ -1075,7 +1102,7 @@ XPC_XOW_Construct(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
return ThrowException(NS_ERROR_FAILURE, cx);
}
nsresult rv = CanAccessWrapper(cx, wrappedObj, nsnull);
nsresult rv = CanAccessWrapper(cx, realObj, wrappedObj, nsnull);
if (NS_FAILED(rv)) {
if (rv == NS_ERROR_DOM_PROP_ACCESS_DENIED) {
// Can't construct.
@ -1102,7 +1129,7 @@ XPC_XOW_HasInstance(JSContext *cx, JSObject *obj, jsval v, JSBool *bp)
return ThrowException(NS_ERROR_FAILURE, cx);
}
nsresult rv = CanAccessWrapper(cx, iface, nsnull);
nsresult rv = CanAccessWrapper(cx, obj, iface, nsnull);
if (NS_FAILED(rv)) {
if (rv == NS_ERROR_DOM_PROP_ACCESS_DENIED) {
// Don't do this test across origins.
@ -1188,7 +1215,7 @@ XPC_XOW_Iterator(JSContext *cx, JSObject *obj, JSBool keysonly)
return nsnull;
}
nsresult rv = CanAccessWrapper(cx, wrappedObj, nsnull);
nsresult rv = CanAccessWrapper(cx, obj, wrappedObj, nsnull);
if (NS_FAILED(rv)) {
if (rv == NS_ERROR_DOM_PROP_ACCESS_DENIED) {
// Can't create iterators for foreign objects.
@ -1253,7 +1280,7 @@ XPC_XOW_toString(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
return ThrowException(NS_ERROR_FAILURE, cx);
}
nsresult rv = CanAccessWrapper(cx, wrappedObj, nsnull);
nsresult rv = CanAccessWrapper(cx, obj, wrappedObj, nsnull);
if (rv == NS_ERROR_DOM_PROP_ACCESS_DENIED) {
nsIScriptSecurityManager *ssm = GetSecurityManager();
if (!ssm) {

Просмотреть файл

@ -79,7 +79,7 @@ Unwrap(JSContext *cx, JSObject *wrapper)
JSObject *wrappedObj =
XPCSafeJSObjectWrapper::GetUnsafeObject(cx, wrapper);
if (NS_FAILED(XPCCrossOriginWrapper::CanAccessWrapper(cx, wrappedObj, nsnull))) {
if (NS_FAILED(XPCCrossOriginWrapper::CanAccessWrapper(cx, nsnull, wrappedObj, nsnull))) {
JS_ClearPendingException(cx);
return nsnull;

Просмотреть файл

@ -92,7 +92,8 @@ WrapperMoved(JSContext *cx, XPCWrappedNative *innerObj,
// If we are "same origin" because UniversalXPConnect is enabled and
// privilegeEnabled is non-null, then privilegeEnabled is set to true.
nsresult
CanAccessWrapper(JSContext *cx, JSObject *wrappedObj, JSBool *privilegeEnabled);
CanAccessWrapper(JSContext *cx, JSObject *outerObj, JSObject *wrappedObj,
JSBool *privilegeEnabled);
// Some elements can change their principal or otherwise need XOWs, even
// if they're same origin. This function returns 'true' if the element's
@ -354,18 +355,20 @@ UnwrapSOW(JSContext *cx, JSObject *wrapper)
inline JSObject *
UnwrapXOW(JSContext *cx, JSObject *wrapper)
{
wrapper = UnwrapGeneric(cx, &XPCCrossOriginWrapper::XOWClass, wrapper);
if (!wrapper) {
JSObject *innerObj =
UnwrapGeneric(cx, &XPCCrossOriginWrapper::XOWClass, wrapper);
if (!innerObj) {
return nsnull;
}
nsresult rv = XPCCrossOriginWrapper::CanAccessWrapper(cx, wrapper, nsnull);
nsresult rv =
XPCCrossOriginWrapper::CanAccessWrapper(cx, wrapper, innerObj, nsnull);
if (NS_FAILED(rv)) {
JS_ClearPendingException(cx);
wrapper = nsnull;
return nsnull;
}
return wrapper;
return innerObj;
}
inline JSObject *
@ -376,7 +379,7 @@ UnwrapCOW(JSContext *cx, JSObject *wrapper)
return nsnull;
}
nsresult rv = XPCCrossOriginWrapper::CanAccessWrapper(cx, wrapper, nsnull);
nsresult rv = XPCCrossOriginWrapper::CanAccessWrapper(cx, nsnull, wrapper, nsnull);
if (NS_FAILED(rv)) {
JS_ClearPendingException(cx);
wrapper = nsnull;