Get principals for XPConnect wrapped natives off their scope instead of walking
their parent chain. Add some asserts to check that this actually does give the same result, which it should with splitwindow. Bug 289655, r=dbradley, sr=jst
This commit is contained in:
Родитель
d1a30bdd5f
Коммит
d295c6f94f
|
@ -386,7 +386,11 @@ private:
|
|||
// Returns null if a principal cannot be found; generally callers
|
||||
// should error out at that point.
|
||||
static nsIPrincipal*
|
||||
doGetObjectPrincipal(JSContext *cx, JSObject *obj);
|
||||
doGetObjectPrincipal(JSContext *cx, JSObject *obj
|
||||
#ifdef DEBUG
|
||||
, PRBool aAllowShortCircuit = PR_TRUE
|
||||
#endif
|
||||
);
|
||||
|
||||
// Returns null if a principal cannot be found. Note that rv can be NS_OK
|
||||
// when this happens -- this means that there was no JS running.
|
||||
|
|
|
@ -2083,7 +2083,11 @@ nsScriptSecurityManager::GetObjectPrincipal(JSContext *aCx, JSObject *aObj,
|
|||
|
||||
// static
|
||||
nsIPrincipal*
|
||||
nsScriptSecurityManager::doGetObjectPrincipal(JSContext *aCx, JSObject *aObj)
|
||||
nsScriptSecurityManager::doGetObjectPrincipal(JSContext *aCx, JSObject *aObj
|
||||
#ifdef DEBUG
|
||||
, PRBool aAllowShortCircuit
|
||||
#endif
|
||||
)
|
||||
{
|
||||
NS_ASSERTION(aCx && aObj, "Bad call to doGetObjectPrincipal()!");
|
||||
nsIPrincipal* result = nsnull;
|
||||
|
@ -2097,7 +2101,6 @@ nsScriptSecurityManager::doGetObjectPrincipal(JSContext *aCx, JSObject *aObj)
|
|||
{
|
||||
// No need to refcount |priv| here.
|
||||
nsISupports *priv = (nsISupports *)JS_GetPrivate(aCx, aObj);
|
||||
nsCOMPtr<nsIScriptObjectPrincipal> objPrin;
|
||||
|
||||
/*
|
||||
* If it's a wrapped native (as most
|
||||
|
@ -2107,16 +2110,37 @@ nsScriptSecurityManager::doGetObjectPrincipal(JSContext *aCx, JSObject *aObj)
|
|||
nsCOMPtr<nsIXPConnectWrappedNative> xpcWrapper =
|
||||
do_QueryInterface(priv);
|
||||
|
||||
if (xpcWrapper)
|
||||
if (NS_LIKELY(xpcWrapper != nsnull))
|
||||
{
|
||||
objPrin = do_QueryWrappedNative(xpcWrapper);
|
||||
#ifdef DEBUG
|
||||
if (aAllowShortCircuit)
|
||||
{
|
||||
#endif
|
||||
result = xpcWrapper->GetObjectPrincipal();
|
||||
#ifdef DEBUG
|
||||
}
|
||||
else
|
||||
{
|
||||
nsCOMPtr<nsIScriptObjectPrincipal> objPrin;
|
||||
objPrin = do_QueryWrappedNative(xpcWrapper);
|
||||
if (objPrin)
|
||||
{
|
||||
result = objPrin->GetPrincipal();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
nsCOMPtr<nsIScriptObjectPrincipal> objPrin;
|
||||
objPrin = do_QueryInterface(priv);
|
||||
if (objPrin)
|
||||
{
|
||||
result = objPrin->GetPrincipal();
|
||||
}
|
||||
}
|
||||
|
||||
if (objPrin && (result = objPrin->GetPrincipal()))
|
||||
if (result)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
@ -2125,6 +2149,10 @@ nsScriptSecurityManager::doGetObjectPrincipal(JSContext *aCx, JSObject *aObj)
|
|||
aObj = JS_GetParent(aCx, aObj);
|
||||
} while (aObj);
|
||||
|
||||
NS_ASSERTION(!aAllowShortCircuit ||
|
||||
result == doGetObjectPrincipal(aCx, aObj, PR_FALSE),
|
||||
"Principal mismatch. Not good");
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
@ -147,6 +147,12 @@ interface nsIXPConnectWrappedNative;
|
|||
interface nsIInterfaceInfo;
|
||||
interface nsIXPCSecurityManager;
|
||||
|
||||
%{C++
|
||||
#ifndef XPCONNECT_STANDALONE
|
||||
class nsIPrincipal;
|
||||
#endif
|
||||
%}
|
||||
|
||||
/***************************************************************************/
|
||||
[uuid(8916a320-d118-11d3-8f3a-0010a4e73d9a)]
|
||||
interface nsIXPConnectJSObjectHolder : nsISupports
|
||||
|
@ -154,7 +160,7 @@ interface nsIXPConnectJSObjectHolder : nsISupports
|
|||
readonly attribute JSObjectPtr JSObject;
|
||||
};
|
||||
|
||||
[uuid(215DBE02-94A7-11d2-BA58-00805F8A5DD7)]
|
||||
[uuid(7021D99D-6344-4CC0-96E7-943ED58792B8)]
|
||||
interface nsIXPConnectWrappedNative : nsIXPConnectJSObjectHolder
|
||||
{
|
||||
/* attribute 'JSObject' inherited from nsIXPConnectJSObjectHolder */
|
||||
|
@ -179,12 +185,28 @@ interface nsIXPConnectWrappedNative : nsIXPConnectJSObjectHolder
|
|||
*/
|
||||
voidPtrPtr GetSecurityInfoAddress();
|
||||
|
||||
/*
|
||||
* NOTE: Add new IDL methods _before_ the C++ block below if you
|
||||
* add them. Otherwise the vtable won't be what xpidl thinks it
|
||||
* is, since GetObjectPrincipal() is virtual.
|
||||
*/
|
||||
|
||||
%{C++
|
||||
/**
|
||||
* Faster access to the native object from C++. Will never return null.
|
||||
*/
|
||||
nsISupports* Native() const { return mIdentity; }
|
||||
|
||||
#ifndef XPCONNECT_STANDALONE
|
||||
/**
|
||||
* Get the object principal for this wrapper. Note that this may well end
|
||||
* up being null; in that case one should seek principals elsewhere. Null
|
||||
* here does NOT indicate system principal or no principals at all, just
|
||||
* that this wrapper doesn't have an intrinsic one.
|
||||
*/
|
||||
virtual nsIPrincipal* GetObjectPrincipal() const = 0;
|
||||
#endif
|
||||
|
||||
protected:
|
||||
nsISupports *mIdentity;
|
||||
public:
|
||||
|
|
|
@ -2250,16 +2250,8 @@ nsXPCComponents_utils_Sandbox::CallOrConstruct(nsIXPConnectWrappedNative *wrappe
|
|||
if (!sandbox)
|
||||
return ThrowAndFail(NS_ERROR_XPC_UNEXPECTED, cx, _retval);
|
||||
|
||||
rv = xpc->InitClasses(cx, sandbox);
|
||||
if (NS_SUCCEEDED(rv) &&
|
||||
!JS_DefineFunctions(cx, sandbox, SandboxFunctions)) {
|
||||
rv = NS_ERROR_FAILURE;
|
||||
}
|
||||
if (NS_FAILED(rv))
|
||||
return ThrowAndFail(NS_ERROR_XPC_UNEXPECTED, cx, _retval);
|
||||
|
||||
// Make sure to set up principals on the sandbox before initing classes
|
||||
nsIScriptObjectPrincipal *sop = nsnull;
|
||||
|
||||
if (JSVAL_IS_STRING(argv[0])) {
|
||||
JSString *codebasestr = JSVAL_TO_STRING(argv[0]);
|
||||
nsCAutoString codebase(JS_GetStringBytes(codebasestr),
|
||||
|
@ -2316,6 +2308,17 @@ nsXPCComponents_utils_Sandbox::CallOrConstruct(nsIXPConnectWrappedNative *wrappe
|
|||
return ThrowAndFail(NS_ERROR_XPC_UNEXPECTED, cx, _retval);
|
||||
}
|
||||
|
||||
// After this point |sop| will be released when |sandbox| is
|
||||
// finalized, so no need to worry about it from now on.
|
||||
|
||||
rv = xpc->InitClasses(cx, sandbox);
|
||||
if (NS_SUCCEEDED(rv) &&
|
||||
!JS_DefineFunctions(cx, sandbox, SandboxFunctions)) {
|
||||
rv = NS_ERROR_FAILURE;
|
||||
}
|
||||
if (NS_FAILED(rv))
|
||||
return ThrowAndFail(NS_ERROR_XPC_UNEXPECTED, cx, _retval);
|
||||
|
||||
if (vp)
|
||||
*vp = OBJECT_TO_JSVAL(sandbox);
|
||||
|
||||
|
|
|
@ -109,8 +109,11 @@
|
|||
#include "nsSupportsArray.h"
|
||||
|
||||
#include "nsIXPCScriptNotify.h" // used to notify: ScriptEvaluated
|
||||
|
||||
#ifndef XPCONNECT_STANDALONE
|
||||
#define XPC_USE_SECURITY_CHECKED_COMPONENT
|
||||
#include "nsIScriptObjectPrincipal.h"
|
||||
#include "nsIPrincipal.h"
|
||||
#endif
|
||||
|
||||
#ifdef XPC_USE_SECURITY_CHECKED_COMPONENT
|
||||
|
@ -1025,6 +1028,13 @@ public:
|
|||
JSObject*
|
||||
GetPrototypeJSObject() const {return mPrototypeJSObject;}
|
||||
|
||||
#ifndef XPCONNECT_STANDALONE
|
||||
nsIPrincipal*
|
||||
GetPrincipal() const
|
||||
{return mScriptObjectPrincipal ?
|
||||
mScriptObjectPrincipal->GetPrincipal() : nsnull;}
|
||||
#endif
|
||||
|
||||
JSObject*
|
||||
GetPrototypeJSFunction() const {return mPrototypeJSFunction;}
|
||||
|
||||
|
@ -1088,9 +1098,22 @@ private:
|
|||
ClassInfo2WrappedNativeProtoMap* mWrappedNativeProtoMap;
|
||||
nsXPCComponents* mComponents;
|
||||
XPCWrappedNativeScope* mNext;
|
||||
// The JS global object for this scope. If non-null, this will be the
|
||||
// default parent for the XPCWrappedNatives that have us as the scope,
|
||||
// unless a PreCreate hook overrides it. Note that this _may_ be null (see
|
||||
// constructor).
|
||||
JSObject* mGlobalJSObject;
|
||||
JSObject* mPrototypeJSObject;
|
||||
JSObject* mPrototypeJSFunction;
|
||||
|
||||
#ifndef XPCONNECT_STANDALONE
|
||||
// The script object principal instance corresponding to our current global
|
||||
// JS object.
|
||||
// XXXbz what happens if someone calls JS_SetPrivate on mGlobalJSObject.
|
||||
// How do we deal? Do we need to? I suspect this isn't worth worrying
|
||||
// about, since all of our scope objects are verified as not doing that.
|
||||
nsCOMPtr<nsIScriptObjectPrincipal> mScriptObjectPrincipal;
|
||||
#endif
|
||||
};
|
||||
|
||||
/***************************************************************************/
|
||||
|
@ -1787,6 +1810,10 @@ public:
|
|||
NS_DECL_NSIXPCONNECTJSOBJECTHOLDER
|
||||
NS_DECL_NSIXPCONNECTWRAPPEDNATIVE
|
||||
|
||||
#ifndef XPCONNECT_STANDALONE
|
||||
virtual nsIPrincipal* GetObjectPrincipal() const;
|
||||
#endif
|
||||
|
||||
JSBool
|
||||
IsValid() const {return nsnull != mFlatJSObject;}
|
||||
|
||||
|
@ -2866,8 +2893,6 @@ private:
|
|||
|
||||
#ifndef XPCONNECT_STANDALONE
|
||||
#include "nsIScriptSecurityManager.h"
|
||||
#include "nsIPrincipal.h"
|
||||
#include "nsIScriptObjectPrincipal.h"
|
||||
|
||||
class BackstagePass : public nsIScriptObjectPrincipal, public nsIXPCScriptable
|
||||
{
|
||||
|
|
|
@ -2360,6 +2360,20 @@ NS_IMETHODIMP XPCWrappedNative::GetJSObjectPrototype(JSObject * *aJSObjectProtot
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
#ifndef XPCONNECT_STANDALONE
|
||||
nsIPrincipal*
|
||||
XPCWrappedNative::GetObjectPrincipal() const
|
||||
{
|
||||
nsIPrincipal* principal = GetScope()->GetPrincipal();
|
||||
#ifdef DEBUG
|
||||
nsCOMPtr<nsIScriptObjectPrincipal> objPrin(do_QueryInterface(mIdentity));
|
||||
NS_ASSERTION(!objPrin || objPrin->GetPrincipal() == principal,
|
||||
"Principal mismatch. Expect bad things to happen");
|
||||
#endif
|
||||
return principal;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* readonly attribute nsIXPConnect XPConnect; */
|
||||
NS_IMETHODIMP XPCWrappedNative::GetXPConnect(nsIXPConnect * *aXPConnect)
|
||||
{
|
||||
|
|
|
@ -176,6 +176,31 @@ XPCWrappedNativeScope::SetGlobal(XPCCallContext& ccx, JSObject* aGlobal)
|
|||
// nsXPConnect::InitClassesWithNewWrappedGlobal.
|
||||
|
||||
mGlobalJSObject = aGlobal;
|
||||
#ifndef XPCONNECT_STANDALONE
|
||||
mScriptObjectPrincipal = nsnull;
|
||||
// Now init our script object principal, if the new global has one
|
||||
if (aGlobal)
|
||||
{
|
||||
JSContext* cx = ccx.GetJSContext();
|
||||
const JSClass* jsClass = JS_GetClass(cx, aGlobal);
|
||||
if (jsClass && !(~jsClass->flags & (JSCLASS_HAS_PRIVATE |
|
||||
JSCLASS_PRIVATE_IS_NSISUPPORTS)))
|
||||
{
|
||||
// Our global has an nsISupports native pointer. Let's
|
||||
// see whether it's what we want.
|
||||
nsISupports* priv = (nsISupports*)JS_GetPrivate(cx, aGlobal);
|
||||
nsCOMPtr<nsIXPConnectWrappedNative> native =
|
||||
do_QueryInterface(priv);
|
||||
if (native)
|
||||
{
|
||||
mScriptObjectPrincipal = do_QueryWrappedNative(native);
|
||||
}
|
||||
if (!mScriptObjectPrincipal) {
|
||||
mScriptObjectPrincipal = do_QueryInterface(priv);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// Lookup 'globalObject.Object.prototype' for our wrapper's proto
|
||||
{
|
||||
|
|
Загрузка…
Ссылка в новой задаче