mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-27 23:02:20 +00:00
bug 728250 - remove JSPrincipals::codebase. r=:luke,:bz
In just 2 cases where JSPrincipals::codebase is used it can be reconstructed from the values stored in the associated nsJSPrincipal. In addition the patch makes nsJSprincipals to inherit both from nsIPrincipal and JSPrincipals allowing to use static_cast to convert between nsIPrincipal and JSPrincipals pointers and to drop many cases of manual JSPrincipal reference counting.
This commit is contained in:
parent
a4e916975c
commit
524dbd7e47
@ -52,7 +52,7 @@ interface nsIContentSecurityPolicy;
|
||||
[ptr] native JSContext(JSContext);
|
||||
[ptr] native JSPrincipals(JSPrincipals);
|
||||
|
||||
[scriptable, uuid(1f83b0e0-6b63-4bdc-a50a-b9afe256bd25)]
|
||||
[scriptable, uuid(f8c4c89a-d726-421b-8415-3e34b241175b)]
|
||||
interface nsIPrincipal : nsISerializable
|
||||
{
|
||||
/**
|
||||
@ -96,12 +96,6 @@ interface nsIPrincipal : nsISerializable
|
||||
*/
|
||||
[noscript] readonly attribute unsigned long hashValue;
|
||||
|
||||
/**
|
||||
* Returns the JS equivalent of the principal.
|
||||
* @see JSPrincipals.h
|
||||
*/
|
||||
[noscript] JSPrincipals getJSPrincipals(in JSContext cx);
|
||||
|
||||
/**
|
||||
* The domain security policy of the principal.
|
||||
*/
|
||||
|
@ -43,14 +43,47 @@
|
||||
|
||||
class nsCString;
|
||||
|
||||
struct nsJSPrincipals : JSPrincipals
|
||||
struct nsJSPrincipals : nsIPrincipal, JSPrincipals
|
||||
{
|
||||
static nsresult Startup();
|
||||
nsJSPrincipals();
|
||||
nsresult Init(nsIPrincipal* aPrincipal, const nsCString& aCodebase);
|
||||
~nsJSPrincipals(void);
|
||||
static JSBool Subsume(JSPrincipals *jsprin, JSPrincipals *other);
|
||||
static void Destroy(JSPrincipals *jsprin);
|
||||
static JSBool Transcode(JSXDRState *xdr, JSPrincipals **jsprinp);
|
||||
|
||||
nsIPrincipal *nsIPrincipalPtr; // [WEAK] it owns us.
|
||||
/*
|
||||
* Get a weak reference to nsIPrincipal associated with the given JS
|
||||
* principal.
|
||||
*/
|
||||
static nsJSPrincipals* get(JSPrincipals *principals) {
|
||||
nsJSPrincipals *self = static_cast<nsJSPrincipals *>(principals);
|
||||
MOZ_ASSERT_IF(self, self->debugToken == DEBUG_TOKEN);
|
||||
return self;
|
||||
}
|
||||
|
||||
static nsJSPrincipals* get(nsIPrincipal *principal) {
|
||||
nsJSPrincipals *self = static_cast<nsJSPrincipals *>(principal);
|
||||
MOZ_ASSERT_IF(self, self->debugToken == DEBUG_TOKEN);
|
||||
return self;
|
||||
}
|
||||
|
||||
nsJSPrincipals() {
|
||||
refcount = 0;
|
||||
setDebugToken(DEBUG_TOKEN);
|
||||
}
|
||||
|
||||
virtual ~nsJSPrincipals() {
|
||||
setDebugToken(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a string that can be used as JS script filename in error reports.
|
||||
*/
|
||||
virtual void GetScriptLocation(nsACString &aStr) = 0;
|
||||
|
||||
#ifdef DEBUG
|
||||
virtual void dumpImpl() = 0;
|
||||
#endif
|
||||
|
||||
static const uint32_t DEBUG_TOKEN = 0x0bf41760;
|
||||
};
|
||||
|
||||
#endif /* nsJSPrincipals_h__ */
|
||||
|
@ -59,16 +59,16 @@ class nsIURI;
|
||||
|
||||
#define NS_NULLPRINCIPAL_SCHEME "moz-nullprincipal"
|
||||
|
||||
class nsNullPrincipal : public nsIPrincipal
|
||||
class nsNullPrincipal : public nsJSPrincipals
|
||||
{
|
||||
public:
|
||||
nsNullPrincipal();
|
||||
|
||||
// Our refcount is managed by mJSPrincipals. Use this macro to avoid an
|
||||
// Our refcount is managed by nsJSPrincipals. Use this macro to avoid an
|
||||
// extra refcount member.
|
||||
|
||||
// FIXME: bug 327245 -- I sorta wish there were a clean way to share the
|
||||
// mJSPrincipals munging code between the various principal classes without
|
||||
// nsJSPrincipals munging code between the various principal classes without
|
||||
// giving up the NS_DECL_NSIPRINCIPAL goodness.
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_DECL_NSIPRINCIPAL
|
||||
@ -76,10 +76,15 @@ public:
|
||||
|
||||
nsresult Init();
|
||||
|
||||
protected:
|
||||
virtual void GetScriptLocation(nsACString &aStr) MOZ_OVERRIDE;
|
||||
|
||||
#ifdef DEBUG
|
||||
virtual void dumpImpl() MOZ_OVERRIDE;
|
||||
#endif
|
||||
|
||||
protected:
|
||||
virtual ~nsNullPrincipal();
|
||||
|
||||
nsJSPrincipals mJSPrincipals;
|
||||
nsCOMPtr<nsIURI> mURI;
|
||||
};
|
||||
|
||||
|
@ -51,7 +51,7 @@
|
||||
class nsIObjectInputStream;
|
||||
class nsIObjectOutputStream;
|
||||
|
||||
class nsPrincipal : public nsIPrincipal
|
||||
class nsPrincipal : public nsJSPrincipals
|
||||
{
|
||||
public:
|
||||
nsPrincipal();
|
||||
@ -60,7 +60,7 @@ protected:
|
||||
virtual ~nsPrincipal();
|
||||
|
||||
public:
|
||||
// Our refcount is managed by mJSPrincipals. Use this macro to avoid
|
||||
// Our refcount is managed by nsJSPrincipals. Use this macro to avoid
|
||||
// an extra refcount member.
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
public:
|
||||
@ -100,8 +100,13 @@ public:
|
||||
|
||||
static const char sInvalid[];
|
||||
|
||||
virtual void GetScriptLocation(nsACString &aStr) MOZ_OVERRIDE;
|
||||
|
||||
#ifdef DEBUG
|
||||
virtual void dumpImpl() MOZ_OVERRIDE;
|
||||
#endif
|
||||
|
||||
protected:
|
||||
nsJSPrincipals mJSPrincipals;
|
||||
nsTArray< nsAutoPtr<nsHashtable> > mAnnotations;
|
||||
nsHashtable* mCapabilities;
|
||||
nsCString mPrefName;
|
||||
|
@ -428,6 +428,9 @@ private:
|
||||
jsid id, JSAccessMode mode,
|
||||
jsval *vp);
|
||||
|
||||
static JSPrincipals *
|
||||
ObjectPrincipalFinder(JSObject *obj);
|
||||
|
||||
// Decides, based on CSP, whether or not eval() and stuff can be executed.
|
||||
static JSBool
|
||||
ContentSecurityPolicyPermitsJSAction(JSContext *cx);
|
||||
|
@ -50,23 +50,26 @@
|
||||
#define NS_SYSTEMPRINCIPAL_CONTRACTID "@mozilla.org/systemprincipal;1"
|
||||
|
||||
|
||||
class nsSystemPrincipal : public nsIPrincipal
|
||||
class nsSystemPrincipal : public nsJSPrincipals
|
||||
{
|
||||
public:
|
||||
// Our refcount is managed by mJSPrincipals. Use this macro to avoid
|
||||
// Our refcount is managed by nsJSPrincipals. Use this macro to avoid
|
||||
// an extra refcount member.
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_DECL_NSIPRINCIPAL
|
||||
NS_DECL_NSISERIALIZABLE
|
||||
|
||||
nsresult Init(JSPrincipals **jsprin);
|
||||
|
||||
nsSystemPrincipal();
|
||||
|
||||
virtual void GetScriptLocation(nsACString &aStr) MOZ_OVERRIDE;
|
||||
|
||||
#ifdef DEBUG
|
||||
virtual void dumpImpl() MOZ_OVERRIDE;
|
||||
#endif
|
||||
|
||||
protected:
|
||||
virtual ~nsSystemPrincipal(void);
|
||||
|
||||
nsJSPrincipals mJSPrincipals;
|
||||
// XXX Probably unnecessary. See bug 143559.
|
||||
NS_DECL_OWNINGTHREAD
|
||||
};
|
||||
|
@ -50,46 +50,44 @@
|
||||
#include "nsMemory.h"
|
||||
#include "nsStringBuffer.h"
|
||||
|
||||
static JSBool
|
||||
nsJSPrincipalsSubsume(JSPrincipals *jsprin, JSPrincipals *other)
|
||||
{
|
||||
nsJSPrincipals *nsjsprin = static_cast<nsJSPrincipals *>(jsprin);
|
||||
nsJSPrincipals *nsother = static_cast<nsJSPrincipals *>(other);
|
||||
// for mozilla::dom::workers::kJSPrincipalsDebugToken
|
||||
#include "mozilla/dom/workers/Workers.h"
|
||||
|
||||
/* static */ JSBool
|
||||
nsJSPrincipals::Subsume(JSPrincipals *jsprin, JSPrincipals *other)
|
||||
{
|
||||
bool result;
|
||||
nsresult rv = nsjsprin->nsIPrincipalPtr->Subsumes(nsother->nsIPrincipalPtr,
|
||||
&result);
|
||||
nsresult rv = nsJSPrincipals::get(jsprin)->Subsumes(nsJSPrincipals::get(other), &result);
|
||||
return NS_SUCCEEDED(rv) && result;
|
||||
}
|
||||
|
||||
static void
|
||||
nsDestroyJSPrincipals(JSContext *cx, struct JSPrincipals *jsprin)
|
||||
/* static */ void
|
||||
nsJSPrincipals::Destroy(JSPrincipals *jsprin)
|
||||
{
|
||||
nsJSPrincipals *nsjsprin = static_cast<nsJSPrincipals *>(jsprin);
|
||||
// The JS runtime can call this method during the last GC when
|
||||
// nsScriptSecurityManager is destroyed. So we must not assume here that
|
||||
// the security manager still exists.
|
||||
|
||||
nsJSPrincipals *nsjsprin = nsJSPrincipals::get(jsprin);
|
||||
|
||||
// We need to destroy the nsIPrincipal. We'll do this by adding
|
||||
// to the refcount and calling release
|
||||
|
||||
// Note that we don't want to use NS_IF_RELEASE because it will try
|
||||
// to set nsjsprin->nsIPrincipalPtr to nsnull *after* nsjsprin has
|
||||
// already been destroyed.
|
||||
#ifdef NS_BUILD_REFCNT_LOGGING
|
||||
// The refcount logging considers AddRef-to-1 to indicate creation,
|
||||
// so trick it into thinking it's otherwise, but balance the
|
||||
// Release() we do below.
|
||||
nsjsprin->refcount++;
|
||||
nsjsprin->nsIPrincipalPtr->AddRef();
|
||||
nsjsprin->AddRef();
|
||||
nsjsprin->refcount--;
|
||||
#else
|
||||
nsjsprin->refcount++;
|
||||
#endif
|
||||
nsjsprin->nsIPrincipalPtr->Release();
|
||||
// The nsIPrincipal that we release owns the JSPrincipal struct,
|
||||
// so we don't need to worry about "codebase"
|
||||
nsjsprin->Release();
|
||||
}
|
||||
|
||||
static JSBool
|
||||
nsTranscodeJSPrincipals(JSXDRState *xdr, JSPrincipals **jsprinp)
|
||||
/* static */ JSBool
|
||||
nsJSPrincipals::Transcode(JSXDRState *xdr, JSPrincipals **jsprinp)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
@ -107,12 +105,7 @@ nsTranscodeJSPrincipals(JSXDRState *xdr, JSPrincipals **jsprinp)
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
::JS_XDRMemResetData(xdr);
|
||||
|
||||
// Require that GetJSPrincipals has been called already by the
|
||||
// code that compiled the script that owns the principals.
|
||||
nsJSPrincipals *nsjsprin =
|
||||
static_cast<nsJSPrincipals*>(*jsprinp);
|
||||
|
||||
rv = stream->WriteObject(nsjsprin->nsIPrincipalPtr, true);
|
||||
rv = stream->WriteObject(nsJSPrincipals::get(*jsprinp), true);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -141,7 +134,8 @@ nsTranscodeJSPrincipals(JSXDRState *xdr, JSPrincipals **jsprinp)
|
||||
nsMemory::Free(olddata);
|
||||
::JS_XDRMemSetData(xdr, data, size);
|
||||
|
||||
prin->GetJSPrincipals(xdr->cx, jsprinp);
|
||||
*jsprinp = nsJSPrincipals::get(prin);
|
||||
JS_HoldPrincipals(*jsprinp);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -156,69 +150,22 @@ nsTranscodeJSPrincipals(JSXDRState *xdr, JSPrincipals **jsprinp)
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsJSPrincipals::Startup()
|
||||
#ifdef DEBUG
|
||||
|
||||
// Defined here so one can do principals->dump() in the debugger
|
||||
JS_EXPORT_API(void)
|
||||
JSPrincipals::dump()
|
||||
{
|
||||
nsCOMPtr<nsIJSRuntimeService> rtsvc = nsXPConnect::GetXPConnect();
|
||||
if (!rtsvc)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
JSRuntime *rt;
|
||||
rtsvc->GetRuntime(&rt);
|
||||
NS_ASSERTION(rt != nsnull, "no JSRuntime?!");
|
||||
|
||||
JSSecurityCallbacks *callbacks = JS_GetRuntimeSecurityCallbacks(rt);
|
||||
NS_ASSERTION(callbacks, "Need a callbacks struct by now!");
|
||||
|
||||
NS_ASSERTION(!callbacks->principalsTranscoder,
|
||||
"oops, JS_SetPrincipalsTranscoder wars!");
|
||||
|
||||
callbacks->principalsTranscoder = nsTranscodeJSPrincipals;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsJSPrincipals::nsJSPrincipals()
|
||||
{
|
||||
codebase = nsnull;
|
||||
refcount = 0;
|
||||
destroy = nsDestroyJSPrincipals;
|
||||
subsume = nsJSPrincipalsSubsume;
|
||||
nsIPrincipalPtr = nsnull;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsJSPrincipals::Init(nsIPrincipal *aPrincipal, const nsCString& aCodebase)
|
||||
{
|
||||
if (nsIPrincipalPtr) {
|
||||
NS_ERROR("Init called twice!");
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
nsIPrincipalPtr = aPrincipal;
|
||||
nsStringBuffer* buf = nsStringBuffer::FromString(aCodebase);
|
||||
char* data;
|
||||
if (buf) {
|
||||
buf->AddRef();
|
||||
data = static_cast<char*>(buf->Data());
|
||||
if (debugToken == nsJSPrincipals::DEBUG_TOKEN) {
|
||||
static_cast<nsJSPrincipals *>(this)->dumpImpl();
|
||||
} else if (debugToken == mozilla::dom::workers::kJSPrincipalsDebugToken) {
|
||||
fprintf(stderr, "Web Worker principal singleton (%p)\n", this);
|
||||
} else {
|
||||
PRUint32 len = aCodebase.Length();
|
||||
buf = nsStringBuffer::Alloc(len + 1); // addrefs
|
||||
if (!buf) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
data = static_cast<char*>(buf->Data());
|
||||
memcpy(data, aCodebase.get(), len);
|
||||
data[len] = '\0';
|
||||
}
|
||||
|
||||
codebase = data;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsJSPrincipals::~nsJSPrincipals()
|
||||
{
|
||||
if (codebase) {
|
||||
nsStringBuffer::FromData(codebase)->Release();
|
||||
fprintf(stderr,
|
||||
"!!! JSPrincipals (%p) is not nsJSPrincipals instance - bad token: "
|
||||
"actual=0x%x expected=0x%x\n",
|
||||
this, unsigned(debugToken), unsigned(nsJSPrincipals::DEBUG_TOKEN));
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -69,8 +69,8 @@ NS_IMPL_CI_INTERFACE_GETTER2(nsNullPrincipal,
|
||||
NS_IMETHODIMP_(nsrefcnt)
|
||||
nsNullPrincipal::AddRef()
|
||||
{
|
||||
NS_PRECONDITION(PRInt32(mJSPrincipals.refcount) >= 0, "illegal refcnt");
|
||||
nsrefcnt count = PR_ATOMIC_INCREMENT(&mJSPrincipals.refcount);
|
||||
NS_PRECONDITION(PRInt32(refcount) >= 0, "illegal refcnt");
|
||||
nsrefcnt count = PR_ATOMIC_INCREMENT(&refcount);
|
||||
NS_LOG_ADDREF(this, count, "nsNullPrincipal", sizeof(*this));
|
||||
return count;
|
||||
}
|
||||
@ -78,8 +78,8 @@ nsNullPrincipal::AddRef()
|
||||
NS_IMETHODIMP_(nsrefcnt)
|
||||
nsNullPrincipal::Release()
|
||||
{
|
||||
NS_PRECONDITION(0 != mJSPrincipals.refcount, "dup release");
|
||||
nsrefcnt count = PR_ATOMIC_DECREMENT(&mJSPrincipals.refcount);
|
||||
NS_PRECONDITION(0 != refcount, "dup release");
|
||||
nsrefcnt count = PR_ATOMIC_DECREMENT(&refcount);
|
||||
NS_LOG_RELEASE(this, count, "nsNullPrincipal");
|
||||
if (count == 0) {
|
||||
delete this;
|
||||
@ -133,9 +133,24 @@ nsNullPrincipal::Init()
|
||||
mURI = new nsNullPrincipalURI(str);
|
||||
NS_ENSURE_TRUE(mURI, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
return mJSPrincipals.Init(this, str);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsNullPrincipal::GetScriptLocation(nsACString &aStr)
|
||||
{
|
||||
mURI->GetSpec(aStr);
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
void nsNullPrincipal::dumpImpl()
|
||||
{
|
||||
nsCAutoString str;
|
||||
mURI->GetSpec(str);
|
||||
fprintf(stderr, "nsNullPrincipal (%p) = %s\n", this, str.get());
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* nsIPrincipal implementation
|
||||
*/
|
||||
@ -179,17 +194,6 @@ nsNullPrincipal::GetHashValue(PRUint32 *aResult)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNullPrincipal::GetJSPrincipals(JSContext *cx, JSPrincipals **aJsprin)
|
||||
{
|
||||
NS_PRECONDITION(mJSPrincipals.nsIPrincipalPtr,
|
||||
"mJSPrincipals is uninitalized!");
|
||||
|
||||
JSPRINCIPALS_HOLD(cx, &mJSPrincipals);
|
||||
*aJsprin = &mJSPrincipals;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNullPrincipal::GetSecurityPolicy(void** aSecurityPolicy)
|
||||
{
|
||||
|
@ -93,9 +93,9 @@ NS_IMPL_CI_INTERFACE_GETTER2(nsPrincipal,
|
||||
NS_IMETHODIMP_(nsrefcnt)
|
||||
nsPrincipal::AddRef()
|
||||
{
|
||||
NS_PRECONDITION(PRInt32(mJSPrincipals.refcount) >= 0, "illegal refcnt");
|
||||
NS_PRECONDITION(PRInt32(refcount) >= 0, "illegal refcnt");
|
||||
// XXXcaa does this need to be threadsafe? See bug 143559.
|
||||
nsrefcnt count = PR_ATOMIC_INCREMENT(&mJSPrincipals.refcount);
|
||||
nsrefcnt count = PR_ATOMIC_INCREMENT(&refcount);
|
||||
NS_LOG_ADDREF(this, count, "nsPrincipal", sizeof(*this));
|
||||
return count;
|
||||
}
|
||||
@ -103,8 +103,8 @@ nsPrincipal::AddRef()
|
||||
NS_IMETHODIMP_(nsrefcnt)
|
||||
nsPrincipal::Release()
|
||||
{
|
||||
NS_PRECONDITION(0 != mJSPrincipals.refcount, "dup release");
|
||||
nsrefcnt count = PR_ATOMIC_DECREMENT(&mJSPrincipals.refcount);
|
||||
NS_PRECONDITION(0 != refcount, "dup release");
|
||||
nsrefcnt count = PR_ATOMIC_DECREMENT(&refcount);
|
||||
NS_LOG_RELEASE(this, count, "nsPrincipal");
|
||||
if (count == 0) {
|
||||
delete this;
|
||||
@ -147,24 +147,10 @@ nsPrincipal::Init(const nsACString& aCertFingerprint,
|
||||
mCodebase = NS_TryToMakeImmutable(aCodebase);
|
||||
mCodebaseImmutable = URIIsImmutable(mCodebase);
|
||||
|
||||
nsresult rv;
|
||||
if (!aCertFingerprint.IsEmpty()) {
|
||||
rv = SetCertificate(aCertFingerprint, aSubjectName, aPrettyName, aCert);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
rv = mJSPrincipals.Init(this, mCert->fingerprint);
|
||||
}
|
||||
}
|
||||
else {
|
||||
nsCAutoString spec;
|
||||
rv = mCodebase->GetSpec(spec);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
rv = mJSPrincipals.Init(this, spec);
|
||||
}
|
||||
}
|
||||
if (aCertFingerprint.IsEmpty())
|
||||
return NS_OK;
|
||||
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv), "nsPrincipal::Init() failed");
|
||||
|
||||
return rv;
|
||||
return SetCertificate(aCertFingerprint, aSubjectName, aPrettyName, aCert);
|
||||
}
|
||||
|
||||
nsPrincipal::~nsPrincipal(void)
|
||||
@ -173,16 +159,25 @@ nsPrincipal::~nsPrincipal(void)
|
||||
delete mCapabilities;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPrincipal::GetJSPrincipals(JSContext *cx, JSPrincipals **jsprin)
|
||||
void
|
||||
nsPrincipal::GetScriptLocation(nsACString &aStr)
|
||||
{
|
||||
NS_PRECONDITION(mJSPrincipals.nsIPrincipalPtr, "mJSPrincipals is uninitialized!");
|
||||
|
||||
JSPRINCIPALS_HOLD(cx, &mJSPrincipals);
|
||||
*jsprin = &mJSPrincipals;
|
||||
return NS_OK;
|
||||
if (mCert) {
|
||||
aStr.Assign(mCert->fingerprint);
|
||||
} else {
|
||||
mCodebase->GetSpec(aStr);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
void nsPrincipal::dumpImpl()
|
||||
{
|
||||
nsCAutoString str;
|
||||
GetScriptLocation(str);
|
||||
fprintf(stderr, "nsPrincipal (%p) = %s\n", this, str.get());
|
||||
}
|
||||
#endif
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPrincipal::GetOrigin(char **aOrigin)
|
||||
{
|
||||
@ -883,9 +878,6 @@ nsPrincipal::InitFromPersistent(const char* aPrefName,
|
||||
mTrusted = aTrusted;
|
||||
}
|
||||
|
||||
rv = mJSPrincipals.Init(this, aToken);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
//-- Save the preference name
|
||||
mPrefName = aPrefName;
|
||||
|
||||
|
@ -517,6 +517,13 @@ NS_IMPL_ISUPPORTS4(nsScriptSecurityManager,
|
||||
///////////////////////////////////////////////////
|
||||
|
||||
///////////////// Security Checks /////////////////
|
||||
|
||||
/* static */ JSPrincipals *
|
||||
nsScriptSecurityManager::ObjectPrincipalFinder(JSObject *aObj)
|
||||
{
|
||||
return nsJSPrincipals::get(doGetObjectPrincipal(aObj));
|
||||
}
|
||||
|
||||
JSBool
|
||||
nsScriptSecurityManager::ContentSecurityPolicyPermitsJSAction(JSContext *cx)
|
||||
{
|
||||
@ -537,7 +544,7 @@ nsScriptSecurityManager::ContentSecurityPolicyPermitsJSAction(JSContext *cx)
|
||||
|
||||
if (!subjectPrincipal) {
|
||||
// See bug 553448 for discussion of this case.
|
||||
NS_ASSERTION(!JS_GetSecurityCallbacks(cx)->findObjectPrincipals,
|
||||
NS_ASSERTION(!JS_GetSecurityCallbacks(js::GetRuntime(cx))->findObjectPrincipals,
|
||||
"CSP: Should have been able to find subject principal. "
|
||||
"Reluctantly granting access.");
|
||||
return JS_TRUE;
|
||||
@ -2179,11 +2186,7 @@ nsScriptSecurityManager::GetScriptPrincipal(JSContext *cx,
|
||||
NS_ERROR("Script compiled without principals!");
|
||||
return nsnull;
|
||||
}
|
||||
nsJSPrincipals *nsJSPrin = static_cast<nsJSPrincipals *>(jsp);
|
||||
nsIPrincipal* result = nsJSPrin->nsIPrincipalPtr;
|
||||
if (!result)
|
||||
*rv = NS_ERROR_FAILURE;
|
||||
return result;
|
||||
return nsJSPrincipals::get(jsp);
|
||||
}
|
||||
|
||||
// static
|
||||
@ -3330,7 +3333,6 @@ nsScriptSecurityManager::nsScriptSecurityManager(void)
|
||||
mPrincipals.Init(31);
|
||||
}
|
||||
|
||||
|
||||
nsresult nsScriptSecurityManager::Init()
|
||||
{
|
||||
nsXPConnect* xpconnect = nsXPConnect::GetXPConnect();
|
||||
@ -3365,10 +3367,6 @@ nsresult nsScriptSecurityManager::Init()
|
||||
nsRefPtr<nsSystemPrincipal> system = new nsSystemPrincipal();
|
||||
NS_ENSURE_TRUE(system, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
JSPrincipals *jsprin;
|
||||
rv = system->Init(&jsprin);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
mSystemPrincipal = system;
|
||||
|
||||
//-- Register security check callback in the JS engine
|
||||
@ -3380,20 +3378,19 @@ nsresult nsScriptSecurityManager::Init()
|
||||
rv = runtimeService->GetRuntime(&sRuntime);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
static JSSecurityCallbacks securityCallbacks = {
|
||||
static const JSSecurityCallbacks securityCallbacks = {
|
||||
CheckObjectAccess,
|
||||
NULL,
|
||||
NULL,
|
||||
nsJSPrincipals::Subsume,
|
||||
nsJSPrincipals::Transcode,
|
||||
ObjectPrincipalFinder,
|
||||
ContentSecurityPolicyPermitsJSAction
|
||||
};
|
||||
|
||||
#ifdef DEBUG
|
||||
JSSecurityCallbacks *oldcallbacks =
|
||||
#endif
|
||||
JS_SetRuntimeSecurityCallbacks(sRuntime, &securityCallbacks);
|
||||
NS_ASSERTION(!oldcallbacks, "Someone else set security callbacks!");
|
||||
MOZ_ASSERT(!JS_GetSecurityCallbacks(sRuntime));
|
||||
JS_SetSecurityCallbacks(sRuntime, &securityCallbacks);
|
||||
JS_InitDestroyPrincipalsCallback(sRuntime, nsJSPrincipals::Destroy);
|
||||
|
||||
JS_SetTrustedPrincipals(sRuntime, jsprin);
|
||||
JS_SetTrustedPrincipals(sRuntime, system);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
@ -3417,7 +3414,7 @@ void
|
||||
nsScriptSecurityManager::Shutdown()
|
||||
{
|
||||
if (sRuntime) {
|
||||
JS_SetRuntimeSecurityCallbacks(sRuntime, NULL);
|
||||
JS_SetSecurityCallbacks(sRuntime, NULL);
|
||||
JS_SetTrustedPrincipals(sRuntime, NULL);
|
||||
sRuntime = nsnull;
|
||||
}
|
||||
@ -3445,13 +3442,6 @@ nsScriptSecurityManager::GetScriptSecurityManager()
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
rv = nsJSPrincipals::Startup();
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("can't initialize JS engine security protocol glue!");
|
||||
delete ssManager;
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
rv = sXPConnect->SetDefaultSecurityManager(ssManager,
|
||||
nsIXPCSecurityManager::HOOK_ALL);
|
||||
if (NS_FAILED(rv)) {
|
||||
|
@ -62,8 +62,8 @@ NS_IMPL_CI_INTERFACE_GETTER2(nsSystemPrincipal,
|
||||
NS_IMETHODIMP_(nsrefcnt)
|
||||
nsSystemPrincipal::AddRef()
|
||||
{
|
||||
NS_PRECONDITION(PRInt32(mJSPrincipals.refcount) >= 0, "illegal refcnt");
|
||||
nsrefcnt count = PR_ATOMIC_INCREMENT(&mJSPrincipals.refcount);
|
||||
NS_PRECONDITION(PRInt32(refcount) >= 0, "illegal refcnt");
|
||||
nsrefcnt count = PR_ATOMIC_INCREMENT(&refcount);
|
||||
NS_LOG_ADDREF(this, count, "nsSystemPrincipal", sizeof(*this));
|
||||
return count;
|
||||
}
|
||||
@ -71,8 +71,8 @@ nsSystemPrincipal::AddRef()
|
||||
NS_IMETHODIMP_(nsrefcnt)
|
||||
nsSystemPrincipal::Release()
|
||||
{
|
||||
NS_PRECONDITION(0 != mJSPrincipals.refcount, "dup release");
|
||||
nsrefcnt count = PR_ATOMIC_DECREMENT(&mJSPrincipals.refcount);
|
||||
NS_PRECONDITION(0 != refcount, "dup release");
|
||||
nsrefcnt count = PR_ATOMIC_DECREMENT(&refcount);
|
||||
NS_LOG_RELEASE(this, count, "nsSystemPrincipal");
|
||||
if (count == 0) {
|
||||
delete this;
|
||||
@ -81,13 +81,26 @@ nsSystemPrincipal::Release()
|
||||
return count;
|
||||
}
|
||||
|
||||
static const char SYSTEM_PRINCIPAL_SPEC[] = "[System Principal]";
|
||||
|
||||
void
|
||||
nsSystemPrincipal::GetScriptLocation(nsACString &aStr)
|
||||
{
|
||||
aStr.Assign(SYSTEM_PRINCIPAL_SPEC);
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
void nsSystemPrincipal::dumpImpl()
|
||||
{
|
||||
fprintf(stderr, "nsSystemPrincipal (%p)\n", this);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
///////////////////////////////////////
|
||||
// Methods implementing nsIPrincipal //
|
||||
///////////////////////////////////////
|
||||
|
||||
#define SYSTEM_PRINCIPAL_SPEC "[System Principal]"
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSystemPrincipal::GetPreferences(char** aPrefName, char** aID,
|
||||
char** aSubjectName,
|
||||
@ -280,16 +293,6 @@ nsSystemPrincipal::SetSecurityPolicy(void* aSecurityPolicy)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSystemPrincipal::GetJSPrincipals(JSContext *cx, JSPrincipals **jsprin)
|
||||
{
|
||||
NS_PRECONDITION(mJSPrincipals.nsIPrincipalPtr, "mJSPrincipals is uninitialized!");
|
||||
|
||||
JSPRINCIPALS_HOLD(cx, &mJSPrincipals);
|
||||
*jsprin = &mJSPrincipals;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////
|
||||
// Methods implementing nsISerializable //
|
||||
@ -317,24 +320,6 @@ nsSystemPrincipal::nsSystemPrincipal()
|
||||
{
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsSystemPrincipal::Init(JSPrincipals **jsprin)
|
||||
{
|
||||
// Use an nsCString so we only do the allocation once here and then
|
||||
// share with nsJSPrincipals
|
||||
nsCString str(SYSTEM_PRINCIPAL_SPEC);
|
||||
if (!str.EqualsLiteral(SYSTEM_PRINCIPAL_SPEC)) {
|
||||
NS_WARNING("Out of memory initializing system principal");
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
nsresult rv = mJSPrincipals.Init(this, str);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
*jsprin = &mJSPrincipals;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsSystemPrincipal::~nsSystemPrincipal(void)
|
||||
nsSystemPrincipal::~nsSystemPrincipal()
|
||||
{
|
||||
}
|
||||
|
@ -43,6 +43,7 @@
|
||||
#include "nsIXPConnect.h"
|
||||
#include "jsapi.h"
|
||||
#include "nsJSUtils.h"
|
||||
#include "nsJSPrincipals.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "nsScriptLoader.h"
|
||||
#include "nsIJSContextStack.h"
|
||||
@ -811,15 +812,13 @@ nsFrameScriptExecutor::LoadFrameScriptInternal(const nsAString& aURL)
|
||||
JSObject* global = nsnull;
|
||||
mGlobal->GetJSObject(&global);
|
||||
if (global) {
|
||||
JSPrincipals* jsprin = nsnull;
|
||||
mPrincipal->GetJSPrincipals(mCx, &jsprin);
|
||||
|
||||
uint32 oldopts = JS_GetOptions(mCx);
|
||||
JS_SetOptions(mCx, oldopts | JSOPTION_NO_SCRIPT_RVAL);
|
||||
|
||||
JSScript* script =
|
||||
JS_CompileUCScriptForPrincipals(mCx, nsnull, jsprin,
|
||||
(jschar*)dataString.get(),
|
||||
JS_CompileUCScriptForPrincipals(mCx, nsnull,
|
||||
nsJSPrincipals::get(mPrincipal),
|
||||
static_cast<const jschar*>(dataString.get()),
|
||||
dataString.Length(),
|
||||
url.get(), 1);
|
||||
|
||||
@ -839,8 +838,6 @@ nsFrameScriptExecutor::LoadFrameScriptInternal(const nsAString& aURL)
|
||||
}
|
||||
(void) JS_ExecuteScript(mCx, global, script, nsnull);
|
||||
}
|
||||
//XXX Argh, JSPrincipals are manually refcounted!
|
||||
JSPRINCIPALS_DROP(mCx, jsprin);
|
||||
}
|
||||
}
|
||||
JSContext* unused;
|
||||
|
@ -518,11 +518,10 @@ NS_ScriptErrorReporter(JSContext *cx,
|
||||
innerWindowID = innerWin->WindowID();
|
||||
}
|
||||
}
|
||||
JSPrincipals *prin = report->originPrincipals;
|
||||
nsIPrincipal *principal =
|
||||
prin ? static_cast<nsJSPrincipals*>(prin)->nsIPrincipalPtr : nsnull;
|
||||
nsContentUtils::AddScriptRunner(
|
||||
new ScriptErrorEvent(globalObject, principal, report->lineno,
|
||||
new ScriptErrorEvent(globalObject,
|
||||
nsJSPrincipals::get(report->originPrincipals),
|
||||
report->lineno,
|
||||
report->uctokenptr - report->uclinebuf,
|
||||
report->flags, msg, fileName, sourceLine,
|
||||
report->errorNumber != JSMSG_OUT_OF_MEMORY,
|
||||
@ -1218,8 +1217,7 @@ nsJSContext::EvaluateStringWithValue(const nsAString& aScript,
|
||||
// Safety first: get an object representing the script's principals, i.e.,
|
||||
// the entities who signed this script, or the fully-qualified-domain-name
|
||||
// or "codebase" from which it was loaded.
|
||||
JSPrincipals *jsprin;
|
||||
nsIPrincipal *principal = aPrincipal;
|
||||
nsCOMPtr<nsIPrincipal> principal = aPrincipal;
|
||||
nsresult rv;
|
||||
if (!aPrincipal) {
|
||||
nsIScriptGlobalObject *global = GetGlobalObject();
|
||||
@ -1234,15 +1232,10 @@ nsJSContext::EvaluateStringWithValue(const nsAString& aScript,
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
principal->GetJSPrincipals(mContext, &jsprin);
|
||||
|
||||
// From here on, we must JSPRINCIPALS_DROP(jsprin) before returning...
|
||||
|
||||
bool ok = false;
|
||||
|
||||
rv = sSecurityManager->CanExecuteScripts(mContext, principal, &ok);
|
||||
if (NS_FAILED(rv)) {
|
||||
JSPRINCIPALS_DROP(mContext, jsprin);
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
@ -1253,7 +1246,6 @@ nsJSContext::EvaluateStringWithValue(const nsAString& aScript,
|
||||
nsCOMPtr<nsIJSContextStack> stack =
|
||||
do_GetService("@mozilla.org/js/xpc/ContextStack;1", &rv);
|
||||
if (NS_FAILED(rv) || NS_FAILED(stack->Push(mContext))) {
|
||||
JSPRINCIPALS_DROP(mContext, jsprin);
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
@ -1273,7 +1265,6 @@ nsJSContext::EvaluateStringWithValue(const nsAString& aScript,
|
||||
|
||||
JSAutoEnterCompartment ac;
|
||||
if (!ac.enter(mContext, aScopeObject)) {
|
||||
JSPRINCIPALS_DROP(mContext, jsprin);
|
||||
stack->Pop(nsnull);
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
@ -1282,7 +1273,7 @@ nsJSContext::EvaluateStringWithValue(const nsAString& aScript,
|
||||
|
||||
ok = ::JS_EvaluateUCScriptForPrincipalsVersion(mContext,
|
||||
aScopeObject,
|
||||
jsprin,
|
||||
nsJSPrincipals::get(principal),
|
||||
static_cast<const jschar*>(PromiseFlatString(aScript).get()),
|
||||
aScript.Length(),
|
||||
aURL,
|
||||
@ -1301,9 +1292,6 @@ nsJSContext::EvaluateStringWithValue(const nsAString& aScript,
|
||||
}
|
||||
}
|
||||
|
||||
// Whew! Finally done with these manually ref-counted things.
|
||||
JSPRINCIPALS_DROP(mContext, jsprin);
|
||||
|
||||
// If all went well, convert val to a string (XXXbe unless undefined?).
|
||||
if (ok) {
|
||||
if (aIsUndefined) {
|
||||
@ -1427,12 +1415,8 @@ nsJSContext::EvaluateString(const nsAString& aScript,
|
||||
// Safety first: get an object representing the script's principals, i.e.,
|
||||
// the entities who signed this script, or the fully-qualified-domain-name
|
||||
// or "codebase" from which it was loaded.
|
||||
JSPrincipals *jsprin;
|
||||
nsIPrincipal *principal = aPrincipal;
|
||||
if (aPrincipal) {
|
||||
aPrincipal->GetJSPrincipals(mContext, &jsprin);
|
||||
}
|
||||
else {
|
||||
nsCOMPtr<nsIPrincipal> principal = aPrincipal;
|
||||
if (!aPrincipal) {
|
||||
nsCOMPtr<nsIScriptObjectPrincipal> objPrincipal =
|
||||
do_QueryInterface(GetGlobalObject());
|
||||
if (!objPrincipal)
|
||||
@ -1440,26 +1424,12 @@ nsJSContext::EvaluateString(const nsAString& aScript,
|
||||
principal = objPrincipal->GetPrincipal();
|
||||
if (!principal)
|
||||
return NS_ERROR_FAILURE;
|
||||
principal->GetJSPrincipals(mContext, &jsprin);
|
||||
}
|
||||
|
||||
JSPrincipals *originJSprin;
|
||||
if (aOriginPrincipal) {
|
||||
aOriginPrincipal->GetJSPrincipals(mContext, &originJSprin);
|
||||
} else {
|
||||
originJSprin = nsnull;
|
||||
}
|
||||
|
||||
// From here on, we must JSPRINCIPALS_DROP(jsprin) before returning...
|
||||
|
||||
bool ok = false;
|
||||
|
||||
nsresult rv = sSecurityManager->CanExecuteScripts(mContext, principal, &ok);
|
||||
if (NS_FAILED(rv)) {
|
||||
JSPRINCIPALS_DROP(mContext, jsprin);
|
||||
if (originJSprin) {
|
||||
JSPRINCIPALS_DROP(mContext, originJSprin);
|
||||
}
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
@ -1470,10 +1440,6 @@ nsJSContext::EvaluateString(const nsAString& aScript,
|
||||
nsCOMPtr<nsIJSContextStack> stack =
|
||||
do_GetService("@mozilla.org/js/xpc/ContextStack;1", &rv);
|
||||
if (NS_FAILED(rv) || NS_FAILED(stack->Push(mContext))) {
|
||||
JSPRINCIPALS_DROP(mContext, jsprin);
|
||||
if (originJSprin) {
|
||||
JSPRINCIPALS_DROP(mContext, originJSprin);
|
||||
}
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
@ -1498,15 +1464,12 @@ nsJSContext::EvaluateString(const nsAString& aScript,
|
||||
JSAutoEnterCompartment ac;
|
||||
if (!ac.enter(mContext, aScopeObject)) {
|
||||
stack->Pop(nsnull);
|
||||
JSPRINCIPALS_DROP(mContext, jsprin);
|
||||
if (originJSprin) {
|
||||
JSPRINCIPALS_DROP(mContext, originJSprin);
|
||||
}
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
ok = JS_EvaluateUCScriptForPrincipalsVersionOrigin(
|
||||
mContext, aScopeObject, jsprin, originJSprin,
|
||||
mContext, aScopeObject,
|
||||
nsJSPrincipals::get(principal), nsJSPrincipals::get(aOriginPrincipal),
|
||||
static_cast<const jschar*>(PromiseFlatString(aScript).get()),
|
||||
aScript.Length(), aURL, aLineNo, vp, JSVersion(aVersion));
|
||||
|
||||
@ -1519,12 +1482,6 @@ nsJSContext::EvaluateString(const nsAString& aScript,
|
||||
}
|
||||
}
|
||||
|
||||
// Whew! Finally done with these manually ref-counted things.
|
||||
JSPRINCIPALS_DROP(mContext, jsprin);
|
||||
if (originJSprin) {
|
||||
JSPRINCIPALS_DROP(mContext, originJSprin);
|
||||
}
|
||||
|
||||
// If all went well, convert val to a string if one is wanted.
|
||||
if (ok) {
|
||||
JSAutoRequest ar(mContext);
|
||||
@ -1573,47 +1530,38 @@ nsJSContext::CompileScript(const PRUnichar* aText,
|
||||
|
||||
JSObject* scopeObject = ::JS_GetGlobalObject(mContext);
|
||||
|
||||
JSPrincipals *jsprin;
|
||||
aPrincipal->GetJSPrincipals(mContext, &jsprin);
|
||||
// From here on, we must JSPRINCIPALS_DROP(jsprin) before returning...
|
||||
|
||||
bool ok = false;
|
||||
|
||||
nsresult rv = sSecurityManager->CanExecuteScripts(mContext, aPrincipal, &ok);
|
||||
if (NS_FAILED(rv)) {
|
||||
JSPRINCIPALS_DROP(mContext, jsprin);
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
aScriptObject.drop(); // ensure old object not used on failure...
|
||||
|
||||
// SecurityManager said "ok", but don't compile if aVersion is unknown.
|
||||
// Don't compile if SecurityManager said "not ok" or aVersion is unknown.
|
||||
// Since the caller is responsible for parsing the version strings, we just
|
||||
// check it isn't JSVERSION_UNKNOWN.
|
||||
if (ok && ((JSVersion)aVersion) != JSVERSION_UNKNOWN) {
|
||||
JSAutoRequest ar(mContext);
|
||||
if (!ok || JSVersion(aVersion) == JSVERSION_UNKNOWN)
|
||||
return NS_OK;
|
||||
|
||||
JSAutoRequest ar(mContext);
|
||||
|
||||
JSScript* script =
|
||||
::JS_CompileUCScriptForPrincipalsVersion(mContext,
|
||||
scopeObject,
|
||||
jsprin,
|
||||
static_cast<const jschar*>(aText),
|
||||
aTextLength,
|
||||
aURL,
|
||||
aLineNo,
|
||||
JSVersion(aVersion));
|
||||
if (script) {
|
||||
NS_ASSERTION(aScriptObject.getScriptTypeID()==JAVASCRIPT,
|
||||
"Expecting JS script object holder");
|
||||
rv = aScriptObject.set(script);
|
||||
} else {
|
||||
rv = NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
JSScript* script =
|
||||
::JS_CompileUCScriptForPrincipalsVersion(mContext,
|
||||
scopeObject,
|
||||
nsJSPrincipals::get(aPrincipal),
|
||||
static_cast<const jschar*>(aText),
|
||||
aTextLength,
|
||||
aURL,
|
||||
aLineNo,
|
||||
JSVersion(aVersion));
|
||||
if (!script) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
// Whew! Finally done.
|
||||
JSPRINCIPALS_DROP(mContext, jsprin);
|
||||
return rv;
|
||||
NS_ASSERTION(aScriptObject.getScriptTypeID()==JAVASCRIPT,
|
||||
"Expecting JS script object holder");
|
||||
return aScriptObject.set(script);
|
||||
}
|
||||
|
||||
nsresult
|
||||
@ -1836,17 +1784,15 @@ nsJSContext::CompileFunction(JSObject* aTarget,
|
||||
return NS_ERROR_ILLEGAL_VALUE;
|
||||
}
|
||||
|
||||
JSPrincipals *jsprin = nsnull;
|
||||
|
||||
nsIScriptGlobalObject *global = GetGlobalObject();
|
||||
nsCOMPtr<nsIPrincipal> principal;
|
||||
if (global) {
|
||||
// XXXbe why the two-step QI? speed up via a new GetGlobalObjectData func?
|
||||
nsCOMPtr<nsIScriptObjectPrincipal> globalData = do_QueryInterface(global);
|
||||
if (globalData) {
|
||||
nsIPrincipal *prin = globalData->GetPrincipal();
|
||||
if (!prin)
|
||||
principal = globalData->GetPrincipal();
|
||||
if (!principal)
|
||||
return NS_ERROR_FAILURE;
|
||||
prin->GetJSPrincipals(mContext, &jsprin);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1856,7 +1802,8 @@ nsJSContext::CompileFunction(JSObject* aTarget,
|
||||
|
||||
JSFunction* fun =
|
||||
::JS_CompileUCFunctionForPrincipalsVersion(mContext,
|
||||
aShared ? nsnull : target, jsprin,
|
||||
aShared ? nsnull : target,
|
||||
nsJSPrincipals::get(principal),
|
||||
PromiseFlatCString(aName).get(),
|
||||
aArgCount, aArgArray,
|
||||
static_cast<const jschar*>(PromiseFlatString(aBody).get()),
|
||||
@ -1864,8 +1811,6 @@ nsJSContext::CompileFunction(JSObject* aTarget,
|
||||
aURL, aLineNo,
|
||||
JSVersion(aVersion));
|
||||
|
||||
if (jsprin)
|
||||
JSPRINCIPALS_DROP(mContext, jsprin);
|
||||
if (!fun)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
@ -3768,33 +3713,6 @@ SetMemoryGCSliceTimePrefChangedCallback(const char* aPrefName, void* aClosure)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static JSPrincipals *
|
||||
ObjectPrincipalFinder(JSContext *cx, JSObject *obj)
|
||||
{
|
||||
if (!sSecurityManager)
|
||||
return nsnull;
|
||||
|
||||
nsCOMPtr<nsIPrincipal> principal;
|
||||
nsresult rv =
|
||||
sSecurityManager->GetObjectPrincipal(cx, obj,
|
||||
getter_AddRefs(principal));
|
||||
|
||||
if (NS_FAILED(rv) || !principal) {
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
JSPrincipals *jsPrincipals = nsnull;
|
||||
principal->GetJSPrincipals(cx, &jsPrincipals);
|
||||
|
||||
// nsIPrincipal::GetJSPrincipals() returns a strong reference to the
|
||||
// JS principals, but the caller of this function expects a weak
|
||||
// reference. So we need to release here.
|
||||
|
||||
JSPRINCIPALS_DROP(cx, jsPrincipals);
|
||||
|
||||
return jsPrincipals;
|
||||
}
|
||||
|
||||
JSObject*
|
||||
NS_DOMReadStructuredClone(JSContext* cx,
|
||||
JSStructuredCloneReader* reader,
|
||||
@ -3853,11 +3771,6 @@ nsJSRuntime::Init()
|
||||
|
||||
sPrevGCSliceCallback = js::SetGCSliceCallback(sRuntime, DOMGCSliceCallback);
|
||||
|
||||
JSSecurityCallbacks *callbacks = JS_GetRuntimeSecurityCallbacks(sRuntime);
|
||||
NS_ASSERTION(callbacks, "SecMan should have set security callbacks!");
|
||||
|
||||
callbacks->findObjectPrincipals = ObjectPrincipalFinder;
|
||||
|
||||
// Set up the structured clone callbacks.
|
||||
static JSStructuredCloneCallbacks cloneCallbacks = {
|
||||
NS_DOMReadStructuredClone,
|
||||
@ -3955,14 +3868,6 @@ nsJSRuntime::Shutdown()
|
||||
// We're being shutdown, and there are no more contexts
|
||||
// alive, release the JS runtime service and the security manager.
|
||||
|
||||
if (sRuntimeService && sSecurityManager) {
|
||||
JSSecurityCallbacks *callbacks = JS_GetRuntimeSecurityCallbacks(sRuntime);
|
||||
if (callbacks) {
|
||||
NS_ASSERTION(callbacks->findObjectPrincipals == ObjectPrincipalFinder,
|
||||
"Fighting over the findObjectPrincipals callback!");
|
||||
callbacks->findObjectPrincipals = NULL;
|
||||
}
|
||||
}
|
||||
NS_IF_RELEASE(sRuntimeService);
|
||||
NS_IF_RELEASE(sSecurityManager);
|
||||
}
|
||||
|
@ -40,31 +40,19 @@
|
||||
|
||||
#include "jsapi.h"
|
||||
|
||||
BEGIN_WORKERS_NAMESPACE
|
||||
|
||||
namespace {
|
||||
|
||||
void
|
||||
PrincipalDestroy(JSContext*, JSPrincipals*)
|
||||
{
|
||||
// nothing
|
||||
}
|
||||
|
||||
JSBool
|
||||
PrincipalSubsume(JSPrincipals*, JSPrincipals*)
|
||||
{
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
const char gPrincipalCodebase[] = "Web Worker";
|
||||
|
||||
JSPrincipals gPrincipal = {
|
||||
const_cast<char*>(gPrincipalCodebase),
|
||||
1, PrincipalDestroy, PrincipalSubsume
|
||||
1
|
||||
#ifdef DEBUG
|
||||
, kJSPrincipalsDebugToken
|
||||
#endif
|
||||
};
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
BEGIN_WORKERS_NAMESPACE
|
||||
|
||||
JSPrincipals*
|
||||
GetWorkerPrincipal()
|
||||
{
|
||||
|
@ -157,6 +157,22 @@ SwapToISupportsArray(SmartPtr<T>& aSrc,
|
||||
|
||||
NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(JsWorkerMallocSizeOf, "js-worker")
|
||||
|
||||
struct WorkerJSRuntimeStats : public JS::RuntimeStats
|
||||
{
|
||||
WorkerJSRuntimeStats()
|
||||
: JS::RuntimeStats(JsWorkerMallocSizeOf) { }
|
||||
|
||||
virtual void initExtraCompartmentStats(JSCompartment *c,
|
||||
JS::CompartmentStats *cstats) MOZ_OVERRIDE
|
||||
{
|
||||
MOZ_ASSERT(!cstats->extra);
|
||||
|
||||
// ReportJSRuntimeExplicitTreeStats expects that cstats->extra is a char pointer
|
||||
const char *name = js::IsAtomsCompartment(c) ? "Web Worker Atoms" : "Web Worker";
|
||||
cstats->extra = const_cast<char *>(name);
|
||||
}
|
||||
};
|
||||
|
||||
class WorkerMemoryReporter : public nsIMemoryMultiReporter
|
||||
{
|
||||
WorkerPrivate* mWorkerPrivate;
|
||||
@ -240,8 +256,7 @@ public:
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
|
||||
JS::RuntimeStats rtStats(JsWorkerMallocSizeOf, xpc::GetCompartmentName,
|
||||
xpc::DestroyCompartmentName);
|
||||
WorkerJSRuntimeStats rtStats;
|
||||
nsresult rv = CollectForRuntime(/* isQuick = */false, &rtStats);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
|
@ -123,6 +123,9 @@ protected:
|
||||
WorkerCrossThreadDispatcher*
|
||||
GetWorkerCrossThreadDispatcher(JSContext* aCx, jsval aWorker);
|
||||
|
||||
// Random unique constant to facilitate JSPrincipal debugging
|
||||
const uint32_t kJSPrincipalsDebugToken = 0x7e2df9d2;
|
||||
|
||||
END_WORKERS_NAMESPACE
|
||||
|
||||
#endif /* mozilla_dom_workers_workers_h__ */
|
||||
|
@ -67,6 +67,7 @@
|
||||
#include "nsIXPCScriptable.h"
|
||||
|
||||
#include "nsJSUtils.h"
|
||||
#include "nsJSPrincipals.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#include "nsXULAppAPI.h"
|
||||
|
||||
@ -1058,7 +1059,7 @@ XPCShellEnvironment::~XPCShellEnvironment()
|
||||
mCxStack = nsnull;
|
||||
|
||||
if (mJSPrincipals) {
|
||||
JSPRINCIPALS_DROP(mCx, mJSPrincipals);
|
||||
JS_DropPrincipals(JS_GetRuntime(mCx), mJSPrincipals);
|
||||
}
|
||||
|
||||
JSRuntime* rt = gOldContextCallback ? JS_GetRuntime(mCx) : NULL;
|
||||
@ -1140,10 +1141,8 @@ XPCShellEnvironment::Init()
|
||||
fprintf(stderr, "+++ Failed to obtain SystemPrincipal from ScriptSecurityManager service.\n");
|
||||
} else {
|
||||
// fetch the JS principals and stick in a global
|
||||
rv = principal->GetJSPrincipals(cx, &mJSPrincipals);
|
||||
if (NS_FAILED(rv)) {
|
||||
fprintf(stderr, "+++ Failed to obtain JS principals from SystemPrincipal.\n");
|
||||
}
|
||||
mJSPrincipals = nsJSPrincipals::get(principal);
|
||||
JS_HoldPrincipals(mJSPrincipals);
|
||||
secman->SetSystemPrincipal(principal);
|
||||
}
|
||||
} else {
|
||||
|
@ -1,4 +1,7 @@
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* vim: set ts=8 sw=4 et tw=99 ft=cpp:
|
||||
*
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
@ -61,31 +64,13 @@ struct TypeInferenceSizes
|
||||
size_t temporary;
|
||||
};
|
||||
|
||||
typedef void* (* GetNameCallback)(JSRuntime *rt, JSCompartment *c);
|
||||
typedef void (* DestroyNameCallback)(void *string);
|
||||
|
||||
struct CompartmentStats
|
||||
{
|
||||
CompartmentStats()
|
||||
{
|
||||
CompartmentStats() {
|
||||
memset(this, 0, sizeof(*this));
|
||||
}
|
||||
|
||||
void init(void *name_, DestroyNameCallback destroyName)
|
||||
{
|
||||
name = name_;
|
||||
destroyNameCb = destroyName;
|
||||
}
|
||||
|
||||
~CompartmentStats()
|
||||
{
|
||||
destroyNameCb(name);
|
||||
}
|
||||
|
||||
// Pointer to an nsCString, which we can't use here.
|
||||
void *name;
|
||||
DestroyNameCallback destroyNameCb;
|
||||
|
||||
void *extra;
|
||||
size_t gcHeapArenaHeaders;
|
||||
size_t gcHeapArenaPadding;
|
||||
size_t gcHeapArenaUnused;
|
||||
@ -119,8 +104,7 @@ struct CompartmentStats
|
||||
|
||||
struct RuntimeStats
|
||||
{
|
||||
RuntimeStats(JSMallocSizeOfFun mallocSizeOf, GetNameCallback getNameCb,
|
||||
DestroyNameCallback destroyNameCb)
|
||||
RuntimeStats(JSMallocSizeOfFun mallocSizeOf)
|
||||
: runtimeObject(0)
|
||||
, runtimeAtomsTable(0)
|
||||
, runtimeContexts(0)
|
||||
@ -149,8 +133,6 @@ struct RuntimeStats
|
||||
, compartmentStatsVector()
|
||||
, currCompartmentStats(NULL)
|
||||
, mallocSizeOf(mallocSizeOf)
|
||||
, getNameCb(getNameCb)
|
||||
, destroyNameCb(destroyNameCb)
|
||||
{}
|
||||
|
||||
size_t runtimeObject;
|
||||
@ -183,8 +165,8 @@ struct RuntimeStats
|
||||
CompartmentStats *currCompartmentStats;
|
||||
|
||||
JSMallocSizeOfFun mallocSizeOf;
|
||||
GetNameCallback getNameCb;
|
||||
DestroyNameCallback destroyNameCb;
|
||||
|
||||
virtual void initExtraCompartmentStats(JSCompartment *c, CompartmentStats *cstats) = 0;
|
||||
};
|
||||
|
||||
#ifdef JS_THREADSAFE
|
||||
|
@ -63,7 +63,7 @@ StatsCompartmentCallback(JSRuntime *rt, void *data, JSCompartment *compartment)
|
||||
// CollectRuntimeStats reserves enough space.
|
||||
MOZ_ALWAYS_TRUE(rtStats->compartmentStatsVector.growBy(1));
|
||||
CompartmentStats &cStats = rtStats->compartmentStatsVector.back();
|
||||
cStats.init(rtStats->getNameCb(rt, compartment), rtStats->destroyNameCb);
|
||||
rtStats->initExtraCompartmentStats(compartment, &cStats);
|
||||
rtStats->currCompartmentStats = &cStats;
|
||||
|
||||
// Get the compartment-level numbers.
|
||||
|
@ -156,9 +156,9 @@ Parser::~Parser()
|
||||
{
|
||||
JSContext *cx = context;
|
||||
if (principals)
|
||||
JSPRINCIPALS_DROP(cx, principals);
|
||||
JS_DropPrincipals(cx->runtime, principals);
|
||||
if (originPrincipals)
|
||||
JSPRINCIPALS_DROP(cx, originPrincipals);
|
||||
JS_DropPrincipals(cx->runtime, originPrincipals);
|
||||
cx->tempLifoAlloc().release(tempPoolMark);
|
||||
cx->activeCompilations--;
|
||||
}
|
||||
@ -169,10 +169,10 @@ Parser::setPrincipals(JSPrincipals *prin, JSPrincipals *originPrin)
|
||||
JS_ASSERT(!principals && !originPrincipals);
|
||||
principals = prin;
|
||||
if (principals)
|
||||
JSPRINCIPALS_HOLD(context, principals);
|
||||
JS_HoldPrincipals(principals);
|
||||
originPrincipals = originPrin;
|
||||
if (originPrincipals)
|
||||
JSPRINCIPALS_HOLD(context, originPrincipals);
|
||||
JS_HoldPrincipals(originPrincipals);
|
||||
}
|
||||
|
||||
ObjectBox *
|
||||
|
@ -158,7 +158,7 @@ TokenStream::TokenStream(JSContext *cx, JSPrincipals *prin, JSPrincipals *origin
|
||||
cx(cx), originPrincipals(JSScript::normalizeOriginPrincipals(prin, originPrin))
|
||||
{
|
||||
if (originPrincipals)
|
||||
JSPRINCIPALS_HOLD(cx, originPrincipals);
|
||||
JS_HoldPrincipals(originPrincipals);
|
||||
}
|
||||
|
||||
#ifdef _MSC_VER
|
||||
@ -248,7 +248,7 @@ TokenStream::~TokenStream()
|
||||
if (sourceMap)
|
||||
cx->free_(sourceMap);
|
||||
if (originPrincipals)
|
||||
JSPRINCIPALS_DROP(cx, originPrincipals);
|
||||
JS_DropPrincipals(cx->runtime, originPrincipals);
|
||||
}
|
||||
|
||||
/* Use the fastest available getc. */
|
||||
|
@ -1,18 +1,9 @@
|
||||
#include "tests.h"
|
||||
|
||||
static void
|
||||
Destroy(JSContext *cx, JSPrincipals *prin);
|
||||
|
||||
JSPrincipals system_principals = {
|
||||
(char *)"", 1, Destroy, NULL
|
||||
1
|
||||
};
|
||||
|
||||
static void
|
||||
Destroy(JSContext *cx, JSPrincipals *prin)
|
||||
{
|
||||
JS_ASSERT(prin == &system_principals);
|
||||
}
|
||||
|
||||
JSClass global_class = {
|
||||
"global",
|
||||
JSCLASS_IS_GLOBAL | JSCLASS_GLOBAL_FLAGS,
|
||||
|
@ -52,7 +52,7 @@ BEGIN_TEST(test_cloneScript)
|
||||
END_TEST(test_cloneScript)
|
||||
|
||||
void
|
||||
DestroyPrincipals(JSContext *cx, JSPrincipals *principals)
|
||||
DestroyPrincipals(JSPrincipals *principals)
|
||||
{
|
||||
delete principals;
|
||||
}
|
||||
@ -60,54 +60,38 @@ DestroyPrincipals(JSContext *cx, JSPrincipals *principals)
|
||||
struct Principals : public JSPrincipals
|
||||
{
|
||||
public:
|
||||
Principals(const char *name)
|
||||
Principals()
|
||||
{
|
||||
refcount = 0;
|
||||
codebase = const_cast<char *>(name);
|
||||
destroy = DestroyPrincipals;
|
||||
subsume = NULL;
|
||||
}
|
||||
};
|
||||
|
||||
class AutoDropPrincipals
|
||||
{
|
||||
JSContext *cx;
|
||||
JSRuntime *rt;
|
||||
JSPrincipals *principals;
|
||||
|
||||
public:
|
||||
AutoDropPrincipals(JSContext *cx, JSPrincipals *principals)
|
||||
: cx(cx), principals(principals)
|
||||
AutoDropPrincipals(JSRuntime *rt, JSPrincipals *principals)
|
||||
: rt(rt), principals(principals)
|
||||
{
|
||||
JSPRINCIPALS_HOLD(cx, principals);
|
||||
JS_HoldPrincipals(principals);
|
||||
}
|
||||
|
||||
~AutoDropPrincipals()
|
||||
{
|
||||
JSPRINCIPALS_DROP(cx, principals);
|
||||
JS_DropPrincipals(rt, principals);
|
||||
}
|
||||
};
|
||||
|
||||
JSBool
|
||||
TranscodePrincipals(JSXDRState *xdr, JSPrincipals **principalsp)
|
||||
{
|
||||
return JS_XDRBytes(xdr, reinterpret_cast<char *>(principalsp), sizeof(*principalsp));
|
||||
}
|
||||
|
||||
BEGIN_TEST(test_cloneScriptWithPrincipals)
|
||||
{
|
||||
JSSecurityCallbacks cbs = {
|
||||
NULL,
|
||||
TranscodePrincipals,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
JS_InitDestroyPrincipalsCallback(rt, DestroyPrincipals);
|
||||
|
||||
JS_SetRuntimeSecurityCallbacks(rt, &cbs);
|
||||
|
||||
JSPrincipals *principalsA = new Principals("A");
|
||||
AutoDropPrincipals dropA(cx, principalsA);
|
||||
JSPrincipals *principalsB = new Principals("B");
|
||||
AutoDropPrincipals dropB(cx, principalsB);
|
||||
JSPrincipals *principalsA = new Principals();
|
||||
AutoDropPrincipals dropA(rt, principalsA);
|
||||
JSPrincipals *principalsB = new Principals();
|
||||
AutoDropPrincipals dropB(rt, principalsB);
|
||||
|
||||
JSObject *A, *B;
|
||||
|
||||
|
@ -5,28 +5,19 @@
|
||||
JSPrincipals *sCurrentGlobalPrincipals = NULL;
|
||||
|
||||
JSPrincipals *
|
||||
ObjectPrincipalsFinder(JSContext *, JSObject *)
|
||||
ObjectPrincipalsFinder(JSObject *)
|
||||
{
|
||||
return sCurrentGlobalPrincipals;
|
||||
}
|
||||
|
||||
JSSecurityCallbacks seccb = {
|
||||
static const JSSecurityCallbacks seccb = {
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
ObjectPrincipalsFinder,
|
||||
NULL
|
||||
};
|
||||
|
||||
static void
|
||||
Destroy(JSContext *, JSPrincipals *)
|
||||
{}
|
||||
|
||||
static JSBool
|
||||
Subsume(JSPrincipals *, JSPrincipals *)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
JSPrincipals *sOriginPrincipalsInErrorReporter = NULL;
|
||||
|
||||
static void
|
||||
@ -35,14 +26,12 @@ ErrorReporter(JSContext *cx, const char *message, JSErrorReport *report)
|
||||
sOriginPrincipalsInErrorReporter = report->originPrincipals;
|
||||
}
|
||||
|
||||
char p1str[] = "principal1";
|
||||
JSPrincipals prin1 = { p1str, 0, Destroy, Subsume };
|
||||
char p2str[] = "principal2";
|
||||
JSPrincipals prin2 = { p2str, 0, Destroy, Subsume };
|
||||
JSPrincipals prin1 = { 1 };
|
||||
JSPrincipals prin2 = { 1 };
|
||||
|
||||
BEGIN_TEST(testOriginPrincipals)
|
||||
{
|
||||
JS_SetContextSecurityCallbacks(cx, &seccb);
|
||||
JS_SetSecurityCallbacks(rt, &seccb);
|
||||
|
||||
/*
|
||||
* Currently, the only way to set a non-trivial originPrincipal is to use
|
||||
|
@ -72,23 +72,11 @@ FreezeThaw(JSContext *cx, JSObject *funobj)
|
||||
return FreezeThawImpl(cx, funobj, JS_XDRFunctionObject);
|
||||
}
|
||||
|
||||
static JSBool
|
||||
SubsumePrincipals(JSPrincipals *, JSPrincipals *)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
static JSPrincipals testPrincipals[] = {
|
||||
{ const_cast<char *>("foo.bar"), 1, NULL, SubsumePrincipals },
|
||||
{ const_cast<char *>("dot.com"), 1, NULL, SubsumePrincipals },
|
||||
{ 1 },
|
||||
{ 1 },
|
||||
};
|
||||
|
||||
static JSBool
|
||||
CheckAccess(JSContext *cx, JSObject *obj, jsid id, JSAccessMode mode, jsval *vp)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
static JSBool
|
||||
TranscodePrincipals(JSXDRState *xdr, JSPrincipals **principalsp)
|
||||
{
|
||||
@ -110,7 +98,7 @@ TranscodePrincipals(JSXDRState *xdr, JSPrincipals **principalsp)
|
||||
if (index >= mozilla::ArrayLength(testPrincipals))
|
||||
return false;
|
||||
*principalsp = &testPrincipals[index];
|
||||
JSPRINCIPALS_HOLD(xdr->cx, *principalsp);
|
||||
JS_HoldPrincipals(*principalsp);
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -118,14 +106,15 @@ TranscodePrincipals(JSXDRState *xdr, JSPrincipals **principalsp)
|
||||
|
||||
BEGIN_TEST(testXDR_principals)
|
||||
{
|
||||
static JSSecurityCallbacks seccb = {
|
||||
CheckAccess,
|
||||
static const JSSecurityCallbacks seccb = {
|
||||
NULL,
|
||||
NULL,
|
||||
TranscodePrincipals,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
JS_SetRuntimeSecurityCallbacks(rt, &seccb);
|
||||
JS_SetSecurityCallbacks(rt, &seccb);
|
||||
|
||||
JSScript *script;
|
||||
for (int i = TEST_FIRST; i != TEST_END; ++i) {
|
||||
|
@ -696,6 +696,8 @@ JS_IsBuiltinFunctionConstructor(JSFunction *fun)
|
||||
*/
|
||||
static JSBool js_NewRuntimeWasCalled = JS_FALSE;
|
||||
|
||||
static const JSSecurityCallbacks NullSecurityCallbacks = { };
|
||||
|
||||
JSRuntime::JSRuntime()
|
||||
: atomsCompartment(NULL),
|
||||
#ifdef JS_THREADSAFE
|
||||
@ -778,7 +780,8 @@ JSRuntime::JSRuntime()
|
||||
gcHelperThread(thisFromCtor()),
|
||||
#endif
|
||||
debuggerMutations(0),
|
||||
securityCallbacks(NULL),
|
||||
securityCallbacks(const_cast<JSSecurityCallbacks *>(&NullSecurityCallbacks)),
|
||||
destroyPrincipals(NULL),
|
||||
structuredCloneCallbacks(NULL),
|
||||
telemetryCallback(NULL),
|
||||
propertyRemovals(0),
|
||||
@ -4451,55 +4454,31 @@ JS_CheckAccess(JSContext *cx, JSObject *obj, jsid id, JSAccessMode mode,
|
||||
return CheckAccess(cx, obj, id, mode, vp, attrsp);
|
||||
}
|
||||
|
||||
#ifdef JS_THREADSAFE
|
||||
JS_PUBLIC_API(int)
|
||||
JS_HoldPrincipals(JSContext *cx, JSPrincipals *principals)
|
||||
JS_PUBLIC_API(void)
|
||||
JS_HoldPrincipals(JSPrincipals *principals)
|
||||
{
|
||||
return JS_ATOMIC_INCREMENT(&principals->refcount);
|
||||
JS_ATOMIC_INCREMENT(&principals->refcount);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(int)
|
||||
JS_DropPrincipals(JSContext *cx, JSPrincipals *principals)
|
||||
JS_PUBLIC_API(void)
|
||||
JS_DropPrincipals(JSRuntime *rt, JSPrincipals *principals)
|
||||
{
|
||||
int rc = JS_ATOMIC_DECREMENT(&principals->refcount);
|
||||
if (rc == 0)
|
||||
principals->destroy(cx, principals);
|
||||
return rc;
|
||||
}
|
||||
#endif
|
||||
|
||||
JS_PUBLIC_API(JSSecurityCallbacks *)
|
||||
JS_SetRuntimeSecurityCallbacks(JSRuntime *rt, JSSecurityCallbacks *callbacks)
|
||||
{
|
||||
JSSecurityCallbacks *oldcallbacks;
|
||||
|
||||
oldcallbacks = rt->securityCallbacks;
|
||||
rt->securityCallbacks = callbacks;
|
||||
return oldcallbacks;
|
||||
rt->destroyPrincipals(principals);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSSecurityCallbacks *)
|
||||
JS_GetRuntimeSecurityCallbacks(JSRuntime *rt)
|
||||
JS_PUBLIC_API(void)
|
||||
JS_SetSecurityCallbacks(JSRuntime *rt, const JSSecurityCallbacks *scb)
|
||||
{
|
||||
return rt->securityCallbacks;
|
||||
JS_ASSERT(scb != &NullSecurityCallbacks);
|
||||
rt->securityCallbacks = scb ? scb : &NullSecurityCallbacks;
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSSecurityCallbacks *)
|
||||
JS_SetContextSecurityCallbacks(JSContext *cx, JSSecurityCallbacks *callbacks)
|
||||
JS_PUBLIC_API(const JSSecurityCallbacks *)
|
||||
JS_GetSecurityCallbacks(JSRuntime *rt)
|
||||
{
|
||||
JSSecurityCallbacks *oldcallbacks;
|
||||
|
||||
oldcallbacks = cx->securityCallbacks;
|
||||
cx->securityCallbacks = callbacks;
|
||||
return oldcallbacks;
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSSecurityCallbacks *)
|
||||
JS_GetSecurityCallbacks(JSContext *cx)
|
||||
{
|
||||
return cx->securityCallbacks
|
||||
? cx->securityCallbacks
|
||||
: cx->runtime->securityCallbacks;
|
||||
return (rt->securityCallbacks != &NullSecurityCallbacks) ? rt->securityCallbacks : NULL;
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(void)
|
||||
@ -4508,6 +4487,14 @@ JS_SetTrustedPrincipals(JSRuntime *rt, JSPrincipals *prin)
|
||||
rt->setTrustedPrincipals(prin);
|
||||
}
|
||||
|
||||
extern JS_PUBLIC_API(void)
|
||||
JS_InitDestroyPrincipalsCallback(JSRuntime *rt, JSDestroyPrincipalsOp destroyPrincipals)
|
||||
{
|
||||
JS_ASSERT(destroyPrincipals);
|
||||
JS_ASSERT(!rt->destroyPrincipals);
|
||||
rt->destroyPrincipals = destroyPrincipals;
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSFunction *)
|
||||
JS_NewFunction(JSContext *cx, JSNative native, unsigned nargs, unsigned flags,
|
||||
JSObject *parent, const char *name)
|
||||
|
@ -1520,6 +1520,12 @@ typedef JSBool
|
||||
* Security protocol types.
|
||||
*/
|
||||
|
||||
typedef void
|
||||
(* JSDestroyPrincipalsOp)(JSPrincipals *principals);
|
||||
|
||||
typedef JSBool
|
||||
(* JSSubsumePrincipalsOp)(JSPrincipals *principals1, JSPrincipals *principals2);
|
||||
|
||||
/*
|
||||
* XDR-encode or -decode a principals instance, based on whether xdr->mode is
|
||||
* JSXDR_ENCODE, in which case *principalsp should be encoded; or JSXDR_DECODE,
|
||||
@ -1539,7 +1545,7 @@ typedef JSBool
|
||||
* callback's implementation.
|
||||
*/
|
||||
typedef JSPrincipals *
|
||||
(* JSObjectPrincipalsFinder)(JSContext *cx, JSObject *obj);
|
||||
(* JSObjectPrincipalsFinder)(JSObject *obj);
|
||||
|
||||
/*
|
||||
* Used to check if a CSP instance wants to disable eval() and friends.
|
||||
@ -4088,52 +4094,48 @@ JS_SetReservedSlot(JSObject *obj, uint32_t index, jsval v);
|
||||
* Security protocol.
|
||||
*/
|
||||
struct JSPrincipals {
|
||||
char *codebase;
|
||||
|
||||
/* Don't call "destroy"; use reference counting macros below. */
|
||||
int refcount;
|
||||
|
||||
void (* destroy)(JSContext *cx, JSPrincipals *);
|
||||
JSBool (* subsume)(JSPrincipals *, JSPrincipals *);
|
||||
};
|
||||
|
||||
#ifdef JS_THREADSAFE
|
||||
#define JSPRINCIPALS_HOLD(cx, principals) JS_HoldPrincipals(cx,principals)
|
||||
#define JSPRINCIPALS_DROP(cx, principals) JS_DropPrincipals(cx,principals)
|
||||
|
||||
extern JS_PUBLIC_API(int)
|
||||
JS_HoldPrincipals(JSContext *cx, JSPrincipals *principals);
|
||||
|
||||
extern JS_PUBLIC_API(int)
|
||||
JS_DropPrincipals(JSContext *cx, JSPrincipals *principals);
|
||||
|
||||
#else
|
||||
#define JSPRINCIPALS_HOLD(cx, principals) (++(principals)->refcount)
|
||||
#define JSPRINCIPALS_DROP(cx, principals) \
|
||||
((--(principals)->refcount == 0) \
|
||||
? ((*(principals)->destroy)((cx), (principals)), 0) \
|
||||
: (principals)->refcount)
|
||||
#ifdef DEBUG
|
||||
/* A helper to facilitate principals debugging. */
|
||||
uint32_t debugToken;
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
void setDebugToken(uint32_t token) {
|
||||
# ifdef DEBUG
|
||||
debugToken = token;
|
||||
# endif
|
||||
}
|
||||
|
||||
/*
|
||||
* This is not defined by the JS engine but should be provided by the
|
||||
* embedding.
|
||||
*/
|
||||
JS_PUBLIC_API(void) dump();
|
||||
#endif
|
||||
};
|
||||
|
||||
extern JS_PUBLIC_API(void)
|
||||
JS_HoldPrincipals(JSPrincipals *principals);
|
||||
|
||||
extern JS_PUBLIC_API(void)
|
||||
JS_DropPrincipals(JSRuntime *rt, JSPrincipals *principals);
|
||||
|
||||
struct JSSecurityCallbacks {
|
||||
JSCheckAccessOp checkObjectAccess;
|
||||
JSSubsumePrincipalsOp subsumePrincipals;
|
||||
JSPrincipalsTranscoder principalsTranscoder;
|
||||
JSObjectPrincipalsFinder findObjectPrincipals;
|
||||
JSCSPEvalChecker contentSecurityPolicyAllows;
|
||||
};
|
||||
|
||||
extern JS_PUBLIC_API(JSSecurityCallbacks *)
|
||||
JS_SetRuntimeSecurityCallbacks(JSRuntime *rt, JSSecurityCallbacks *callbacks);
|
||||
extern JS_PUBLIC_API(void)
|
||||
JS_SetSecurityCallbacks(JSRuntime *rt, const JSSecurityCallbacks *callbacks);
|
||||
|
||||
extern JS_PUBLIC_API(JSSecurityCallbacks *)
|
||||
JS_GetRuntimeSecurityCallbacks(JSRuntime *rt);
|
||||
|
||||
extern JS_PUBLIC_API(JSSecurityCallbacks *)
|
||||
JS_SetContextSecurityCallbacks(JSContext *cx, JSSecurityCallbacks *callbacks);
|
||||
|
||||
extern JS_PUBLIC_API(JSSecurityCallbacks *)
|
||||
JS_GetSecurityCallbacks(JSContext *cx);
|
||||
extern JS_PUBLIC_API(const JSSecurityCallbacks *)
|
||||
JS_GetSecurityCallbacks(JSRuntime *rt);
|
||||
|
||||
/*
|
||||
* Code running with "trusted" principals will be given a deeper stack
|
||||
@ -4150,6 +4152,14 @@ JS_GetSecurityCallbacks(JSContext *cx);
|
||||
extern JS_PUBLIC_API(void)
|
||||
JS_SetTrustedPrincipals(JSRuntime *rt, JSPrincipals *prin);
|
||||
|
||||
/*
|
||||
* Initialize the callback that is called to destroy JSPrincipals instance
|
||||
* when its reference counter drops to zero. The initialization can be done
|
||||
* only once per JS runtime.
|
||||
*/
|
||||
extern JS_PUBLIC_API(void)
|
||||
JS_InitDestroyPrincipalsCallback(JSRuntime *rt, JSDestroyPrincipalsOp destroyPrincipals);
|
||||
|
||||
/************************************************************************/
|
||||
|
||||
/*
|
||||
|
@ -988,7 +988,6 @@ JSContext::JSContext(JSRuntime *rt)
|
||||
#ifdef JS_THREADSAFE
|
||||
outstandingRequests(0),
|
||||
#endif
|
||||
securityCallbacks(NULL),
|
||||
resolveFlags(0),
|
||||
rngSeed(0),
|
||||
iterValue(MagicValue(JS_NO_ITER_VALUE)),
|
||||
|
@ -509,11 +509,8 @@ struct JSRuntime : js::RuntimeFriendFields
|
||||
|
||||
uint32_t debuggerMutations;
|
||||
|
||||
/*
|
||||
* Security callbacks set on the runtime are used by each context unless
|
||||
* an override is set on the context.
|
||||
*/
|
||||
JSSecurityCallbacks *securityCallbacks;
|
||||
const JSSecurityCallbacks *securityCallbacks;
|
||||
JSDestroyPrincipalsOp destroyPrincipals;
|
||||
|
||||
/* Structured data callbacks are runtime-wide. */
|
||||
const JSStructuredCloneCallbacks *structuredCloneCallbacks;
|
||||
@ -1013,9 +1010,6 @@ struct JSContext : js::ContextFriendFields
|
||||
|
||||
#endif /* JSGC_ROOT_ANALYSIS */
|
||||
|
||||
/* Security callbacks that override any defined on the runtime. */
|
||||
JSSecurityCallbacks *securityCallbacks;
|
||||
|
||||
/* Stored here to avoid passing it around as a parameter. */
|
||||
unsigned resolveFlags;
|
||||
|
||||
|
@ -304,8 +304,7 @@ InitExnPrivate(JSContext *cx, JSObject *exnObject, JSString *message,
|
||||
JS_ASSERT(exnObject->isError());
|
||||
JS_ASSERT(!exnObject->getPrivate());
|
||||
|
||||
JSSecurityCallbacks *callbacks = JS_GetSecurityCallbacks(cx);
|
||||
JSCheckAccessOp checkAccess = callbacks ? callbacks->checkObjectAccess : NULL;
|
||||
JSCheckAccessOp checkAccess = cx->runtime->securityCallbacks->checkObjectAccess;
|
||||
|
||||
Vector<JSStackTraceElem> frames(cx);
|
||||
Vector<Value> values(cx);
|
||||
@ -443,7 +442,7 @@ SetExnPrivate(JSContext *cx, JSObject *exnObject, JSExnPrivate *priv)
|
||||
JS_ASSERT(exnObject->isError());
|
||||
if (JSErrorReport *report = priv->errorReport) {
|
||||
if (JSPrincipals *prin = report->originPrincipals)
|
||||
JSPRINCIPALS_HOLD(cx, prin);
|
||||
JS_HoldPrincipals(prin);
|
||||
}
|
||||
exnObject->setPrivate(priv);
|
||||
}
|
||||
@ -455,7 +454,7 @@ exn_finalize(JSContext *cx, JSObject *obj)
|
||||
if (JSErrorReport *report = priv->errorReport) {
|
||||
/* HOLD called by SetExnPrivate. */
|
||||
if (JSPrincipals *prin = report->originPrincipals)
|
||||
JSPRINCIPALS_DROP(cx, prin);
|
||||
JS_DropPrincipals(cx->runtime, prin);
|
||||
cx->free_(report);
|
||||
}
|
||||
cx->free_(priv);
|
||||
|
@ -2915,7 +2915,7 @@ SweepCompartments(JSContext *cx, JSGCInvocationKind gckind)
|
||||
if (callback)
|
||||
JS_ALWAYS_TRUE(callback(cx, compartment, JSCOMPARTMENT_DESTROY));
|
||||
if (compartment->principals)
|
||||
JSPRINCIPALS_DROP(cx, compartment->principals);
|
||||
JS_DropPrincipals(rt, compartment->principals);
|
||||
cx->delete_(compartment);
|
||||
continue;
|
||||
}
|
||||
@ -3905,7 +3905,7 @@ NewCompartment(JSContext *cx, JSPrincipals *principals)
|
||||
compartment->isSystemCompartment = principals && rt->trustedPrincipals() == principals;
|
||||
if (principals) {
|
||||
compartment->principals = principals;
|
||||
JSPRINCIPALS_HOLD(cx, principals);
|
||||
JS_HoldPrincipals(principals);
|
||||
}
|
||||
|
||||
compartment->setGCLastBytes(8192, 8192, GC_NORMAL);
|
||||
|
@ -789,15 +789,15 @@ EvalCacheLookup(JSContext *cx, JSLinearString *str, StackFrame *caller, unsigned
|
||||
|
||||
JSVersion version = cx->findVersion();
|
||||
JSScript *script;
|
||||
JSSubsumePrincipalsOp subsume = cx->runtime->securityCallbacks->subsumePrincipals;
|
||||
while ((script = *scriptp) != NULL) {
|
||||
if (script->savedCallerFun &&
|
||||
script->staticLevel == staticLevel &&
|
||||
script->getVersion() == version &&
|
||||
!script->hasSingletons &&
|
||||
(script->principals == principals ||
|
||||
(principals && script->principals &&
|
||||
principals->subsume(principals, script->principals) &&
|
||||
script->principals->subsume(script->principals, principals)))) {
|
||||
(!subsume || script->principals == principals ||
|
||||
(subsume(principals, script->principals) &&
|
||||
subsume(script->principals, principals)))) {
|
||||
/*
|
||||
* Get the prior (cache-filling) eval's saved caller function.
|
||||
* See frontend::CompileScript.
|
||||
@ -1163,12 +1163,14 @@ obj_watch_handler(JSContext *cx, JSObject *obj, jsid id, jsval old,
|
||||
jsval *nvp, void *closure)
|
||||
{
|
||||
JSObject *callable = (JSObject *) closure;
|
||||
if (JSPrincipals *watcher = callable->principals(cx)) {
|
||||
if (JSObject *scopeChain = cx->stack.currentScriptedScopeChain()) {
|
||||
if (JSPrincipals *subject = scopeChain->principals(cx)) {
|
||||
if (!watcher->subsume(watcher, subject)) {
|
||||
/* Silently don't call the watch handler. */
|
||||
return JS_TRUE;
|
||||
if (JSSubsumePrincipalsOp subsume = cx->runtime->securityCallbacks->subsumePrincipals) {
|
||||
if (JSPrincipals *watcher = callable->principals(cx)) {
|
||||
if (JSObject *scopeChain = cx->stack.currentScriptedScopeChain()) {
|
||||
if (JSPrincipals *subject = scopeChain->principals(cx)) {
|
||||
if (!subsume(watcher, subject)) {
|
||||
/* Silently don't call the watch handler. */
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -5881,10 +5883,7 @@ CheckAccess(JSContext *cx, JSObject *obj, jsid id, JSAccessMode mode,
|
||||
JSBool writing;
|
||||
JSObject *pobj;
|
||||
JSProperty *prop;
|
||||
Class *clasp;
|
||||
const Shape *shape;
|
||||
JSSecurityCallbacks *callbacks;
|
||||
JSCheckAccessOp check;
|
||||
|
||||
while (JS_UNLIKELY(obj->isWith()))
|
||||
obj = obj->getProto();
|
||||
@ -5948,12 +5947,9 @@ CheckAccess(JSContext *cx, JSObject *obj, jsid id, JSAccessMode mode,
|
||||
* hook. This covers precompilation-based sharing and (possibly
|
||||
* unintended) runtime sharing across trust boundaries.
|
||||
*/
|
||||
clasp = pobj->getClass();
|
||||
check = clasp->checkAccess;
|
||||
if (!check) {
|
||||
callbacks = JS_GetSecurityCallbacks(cx);
|
||||
check = callbacks ? callbacks->checkObjectAccess : NULL;
|
||||
}
|
||||
JSCheckAccessOp check = pobj->getClass()->checkAccess;
|
||||
if (!check)
|
||||
check = cx->runtime->securityCallbacks->checkObjectAccess;
|
||||
return !check || check(cx, pobj, id, mode, vp);
|
||||
}
|
||||
|
||||
|
@ -1118,9 +1118,8 @@ JSObject::isCallable()
|
||||
inline JSPrincipals *
|
||||
JSObject::principals(JSContext *cx)
|
||||
{
|
||||
JSSecurityCallbacks *cb = JS_GetSecurityCallbacks(cx);
|
||||
if (JSObjectPrincipalsFinder finder = cb ? cb->findObjectPrincipals : NULL)
|
||||
return finder(cx, this);
|
||||
if (JSObjectPrincipalsFinder find = cx->runtime->securityCallbacks->findObjectPrincipals)
|
||||
return find(this);
|
||||
return cx->compartment ? cx->compartment->principals : NULL;
|
||||
}
|
||||
|
||||
|
@ -703,11 +703,11 @@ XDRScript(JSXDRState *xdr, JSScript **scriptp)
|
||||
JS_ASSERT_IF(script->principals, script->originPrincipals);
|
||||
if (xdr->principals) {
|
||||
script->principals = xdr->principals;
|
||||
JSPRINCIPALS_HOLD(cx, xdr->principals);
|
||||
JS_HoldPrincipals(xdr->principals);
|
||||
}
|
||||
if (xdr->originPrincipals) {
|
||||
script->originPrincipals = xdr->originPrincipals;
|
||||
JSPRINCIPALS_HOLD(cx, xdr->originPrincipals);
|
||||
JS_HoldPrincipals(xdr->originPrincipals);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1256,14 +1256,14 @@ JSScript::NewScriptFromEmitter(JSContext *cx, BytecodeEmitter *bce)
|
||||
script->principals = bce->parser->principals;
|
||||
|
||||
if (script->principals)
|
||||
JSPRINCIPALS_HOLD(cx, script->principals);
|
||||
JS_HoldPrincipals(script->principals);
|
||||
|
||||
/* Establish invariant: principals implies originPrincipals. */
|
||||
script->originPrincipals = bce->parser->originPrincipals;
|
||||
if (!script->originPrincipals)
|
||||
script->originPrincipals = script->principals;
|
||||
if (script->originPrincipals)
|
||||
JSPRINCIPALS_HOLD(cx, script->originPrincipals);
|
||||
JS_HoldPrincipals(script->originPrincipals);
|
||||
|
||||
script->sourceMap = (jschar *) bce->parser->tokenStream.releaseSourceMap();
|
||||
|
||||
@ -1462,9 +1462,9 @@ JSScript::finalize(JSContext *cx, bool background)
|
||||
|
||||
JS_ASSERT_IF(principals, originPrincipals);
|
||||
if (principals)
|
||||
JSPRINCIPALS_DROP(cx, principals);
|
||||
JS_DropPrincipals(cx->runtime, principals);
|
||||
if (originPrincipals)
|
||||
JSPRINCIPALS_DROP(cx, originPrincipals);
|
||||
JS_DropPrincipals(cx->runtime, originPrincipals);
|
||||
|
||||
if (types)
|
||||
types->destroy();
|
||||
|
@ -559,7 +559,7 @@ XDRPrincipals(JSXDRState *xdr)
|
||||
return false;
|
||||
|
||||
if (flags & (HAS_PRINCIPALS | HAS_ORIGIN)) {
|
||||
JSSecurityCallbacks *scb = JS_GetSecurityCallbacks(xdr->cx);
|
||||
const JSSecurityCallbacks *scb = JS_GetSecurityCallbacks(xdr->cx->runtime);
|
||||
if (xdr->mode == JSXDR_DECODE) {
|
||||
if (!scb || !scb->principalsTranscoder) {
|
||||
JS_ReportErrorNumber(xdr->cx, js_GetErrorMessage, NULL,
|
||||
@ -581,7 +581,7 @@ XDRPrincipals(JSXDRState *xdr)
|
||||
return false;
|
||||
} else if (xdr->mode == JSXDR_DECODE && xdr->principals) {
|
||||
xdr->originPrincipals = xdr->principals;
|
||||
JSPRINCIPALS_HOLD(xdr->cx, xdr->principals);
|
||||
JS_HoldPrincipals(xdr->principals);
|
||||
}
|
||||
}
|
||||
|
||||
@ -599,9 +599,9 @@ struct AutoDropXDRPrincipals {
|
||||
~AutoDropXDRPrincipals() {
|
||||
if (xdr->mode == JSXDR_DECODE) {
|
||||
if (xdr->principals)
|
||||
JSPRINCIPALS_DROP(xdr->cx, xdr->principals);
|
||||
JS_DropPrincipals(xdr->cx->runtime, xdr->principals);
|
||||
if (xdr->originPrincipals)
|
||||
JSPRINCIPALS_DROP(xdr->cx, xdr->originPrincipals);
|
||||
JS_DropPrincipals(xdr->cx->runtime, xdr->originPrincipals);
|
||||
}
|
||||
xdr->principals = NULL;
|
||||
xdr->originPrincipals = NULL;
|
||||
|
@ -4867,22 +4867,11 @@ MaybeOverrideOutFileFromEnv(const char* const envVar,
|
||||
}
|
||||
}
|
||||
|
||||
JSBool
|
||||
ShellPrincipalsSubsume(JSPrincipals *, JSPrincipals *)
|
||||
{
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
JSPrincipals shellTrustedPrincipals = {
|
||||
(char *)"[shell trusted principals]",
|
||||
1,
|
||||
NULL, /* nobody should be destroying this */
|
||||
ShellPrincipalsSubsume
|
||||
};
|
||||
/* Set the initial counter to 1 so the principal will never be destroyed. */
|
||||
JSPrincipals shellTrustedPrincipals = { 1 };
|
||||
|
||||
JSBool
|
||||
CheckObjectAccess(JSContext *cx, JSObject *obj, jsid id, JSAccessMode mode,
|
||||
jsval *vp)
|
||||
CheckObjectAccess(JSContext *cx, JSObject *obj, jsid id, JSAccessMode mode, jsval *vp)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@ -4891,6 +4880,7 @@ JSSecurityCallbacks securityCallbacks = {
|
||||
CheckObjectAccess,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
@ -5033,7 +5023,7 @@ main(int argc, char **argv, char **envp)
|
||||
JS_SetGCParameter(rt, JSGC_MAX_BYTES, 0xffffffff);
|
||||
|
||||
JS_SetTrustedPrincipals(rt, &shellTrustedPrincipals);
|
||||
JS_SetRuntimeSecurityCallbacks(rt, &securityCallbacks);
|
||||
JS_SetSecurityCallbacks(rt, &securityCallbacks);
|
||||
|
||||
JS_SetNativeStackQuota(rt, gMaxStackSize);
|
||||
|
||||
|
@ -386,15 +386,12 @@ GlobalObject::isRuntimeCodeGenEnabled(JSContext *cx)
|
||||
{
|
||||
HeapSlot &v = getSlotRef(RUNTIME_CODEGEN_ENABLED);
|
||||
if (v.isUndefined()) {
|
||||
JSSecurityCallbacks *callbacks = JS_GetSecurityCallbacks(cx);
|
||||
|
||||
/*
|
||||
* If there are callbacks, make sure that the CSP callback is installed
|
||||
* and that it permits runtime code generation, then cache the result.
|
||||
*/
|
||||
v.set(this, RUNTIME_CODEGEN_ENABLED,
|
||||
BooleanValue((!callbacks || !callbacks->contentSecurityPolicyAllows) ||
|
||||
callbacks->contentSecurityPolicyAllows(cx)));
|
||||
JSCSPEvalChecker allows = cx->runtime->securityCallbacks->contentSecurityPolicyAllows;
|
||||
v.set(this, RUNTIME_CODEGEN_ENABLED, BooleanValue(!allows || allows(cx)));
|
||||
}
|
||||
return !v.isFalse();
|
||||
}
|
||||
|
@ -80,6 +80,7 @@
|
||||
#include "nsDOMFile.h"
|
||||
#include "jsxdrapi.h"
|
||||
#include "jsprf.h"
|
||||
#include "nsJSPrincipals.h"
|
||||
// For reporting errors with the console service
|
||||
#include "nsIScriptError.h"
|
||||
#include "nsIConsoleService.h"
|
||||
@ -645,17 +646,6 @@ class ANSIFileAutoCloser
|
||||
};
|
||||
#endif
|
||||
|
||||
class JSPrincipalsHolder
|
||||
{
|
||||
public:
|
||||
JSPrincipalsHolder(JSContext *cx, JSPrincipals *principals)
|
||||
: mCx(cx), mPrincipals(principals) {}
|
||||
~JSPrincipalsHolder() { JSPRINCIPALS_DROP(mCx, mPrincipals); }
|
||||
private:
|
||||
JSContext *mCx;
|
||||
JSPrincipals *mPrincipals;
|
||||
};
|
||||
|
||||
nsresult
|
||||
mozJSComponentLoader::GlobalForLocation(nsILocalFile *aComponentFile,
|
||||
nsIURI *aURI,
|
||||
@ -665,7 +655,6 @@ mozJSComponentLoader::GlobalForLocation(nsILocalFile *aComponentFile,
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
JSPrincipals* jsPrincipals = nsnull;
|
||||
JSCLContextHelper cx(this);
|
||||
|
||||
JS_AbortIfWrongThread(JS_GetRuntime(cx));
|
||||
@ -673,11 +662,6 @@ mozJSComponentLoader::GlobalForLocation(nsILocalFile *aComponentFile,
|
||||
// preserve caller's compartment
|
||||
js::AutoPreserveCompartment pc(cx);
|
||||
|
||||
rv = mSystemPrincipal->GetJSPrincipals(cx, &jsPrincipals);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
JSPrincipalsHolder princHolder(mContext, jsPrincipals);
|
||||
|
||||
nsCOMPtr<nsIXPCScriptable> backstagePass;
|
||||
rv = mRuntimeService->GetBackstagePass(getter_AddRefs(backstagePass));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
@ -837,7 +821,9 @@ mozJSComponentLoader::GlobalForLocation(nsILocalFile *aComponentFile,
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
script = JS_CompileScriptForPrincipalsVersion(cx, global, jsPrincipals, buf, fileSize32, nativePath.get(), 1,
|
||||
script = JS_CompileScriptForPrincipalsVersion(cx, global,
|
||||
nsJSPrincipals::get(mSystemPrincipal),
|
||||
buf, fileSize32, nativePath.get(), 1,
|
||||
JSVERSION_LATEST);
|
||||
|
||||
PR_MemUnmap(buf, fileSize32);
|
||||
@ -880,7 +866,9 @@ mozJSComponentLoader::GlobalForLocation(nsILocalFile *aComponentFile,
|
||||
NS_WARNING("Failed to read file");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
script = JS_CompileScriptForPrincipalsVersion(cx, global, jsPrincipals, buf, rlen, nativePath.get(), 1,
|
||||
script = JS_CompileScriptForPrincipalsVersion(cx, global,
|
||||
nsJSPrincipals::get(mSystemPrincipal),
|
||||
buf, rlen, nativePath.get(), 1,
|
||||
JSVERSION_LATEST);
|
||||
|
||||
free(buf);
|
||||
@ -917,7 +905,9 @@ mozJSComponentLoader::GlobalForLocation(nsILocalFile *aComponentFile,
|
||||
|
||||
buf[len] = '\0';
|
||||
|
||||
script = JS_CompileScriptForPrincipalsVersion(cx, global, jsPrincipals, buf, bytesRead, nativePath.get(), 1,
|
||||
script = JS_CompileScriptForPrincipalsVersion(cx, global,
|
||||
nsJSPrincipals::get(mSystemPrincipal),
|
||||
buf, bytesRead, nativePath.get(), 1,
|
||||
JSVERSION_LATEST);
|
||||
}
|
||||
// Propagate the exception, if one exists. Also, don't leave the stale
|
||||
|
@ -61,6 +61,7 @@
|
||||
#include "jsapi.h"
|
||||
#include "jsdbgapi.h"
|
||||
#include "jsfriendapi.h"
|
||||
#include "nsJSPrincipals.h"
|
||||
|
||||
#include "mozilla/FunctionTimer.h"
|
||||
#include "mozilla/scache/StartupCache.h"
|
||||
@ -111,7 +112,6 @@ mozJSSubScriptLoader::ReadScript(nsIURI *uri, JSContext *cx, JSObject *target_ob
|
||||
{
|
||||
nsCOMPtr<nsIChannel> chan;
|
||||
nsCOMPtr<nsIInputStream> instream;
|
||||
JSPrincipals *jsPrincipals;
|
||||
JSErrorReporter er;
|
||||
|
||||
nsresult rv;
|
||||
@ -140,14 +140,6 @@ mozJSSubScriptLoader::ReadScript(nsIURI *uri, JSContext *cx, JSObject *target_ob
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
/* we can't hold onto jsPrincipals as a module var because the
|
||||
* JSPRINCIPALS_DROP macro takes a JSContext, which we won't have in the
|
||||
* destructor */
|
||||
rv = principal->GetJSPrincipals(cx, &jsPrincipals);
|
||||
if (NS_FAILED(rv) || !jsPrincipals) {
|
||||
return ReportError(cx, LOAD_ERROR_NOPRINCIPALS);
|
||||
}
|
||||
|
||||
/* set our own error reporter so we can report any bad things as catchable
|
||||
* exceptions, including the source/line number */
|
||||
er = JS_SetErrorReporter(cx, mozJSLoaderErrorReporter);
|
||||
@ -158,21 +150,18 @@ mozJSSubScriptLoader::ReadScript(nsIURI *uri, JSContext *cx, JSObject *target_ob
|
||||
charset, nsnull, script);
|
||||
|
||||
if (NS_FAILED(rv)) {
|
||||
JSPRINCIPALS_DROP(cx, jsPrincipals);
|
||||
return ReportError(cx, LOAD_ERROR_BADCHARSET);
|
||||
}
|
||||
|
||||
*scriptp =
|
||||
JS_CompileUCScriptForPrincipals(cx, target_obj, jsPrincipals,
|
||||
JS_CompileUCScriptForPrincipals(cx, target_obj, nsJSPrincipals::get(principal),
|
||||
reinterpret_cast<const jschar*>(script.get()),
|
||||
script.Length(), uriStr, 1);
|
||||
} else {
|
||||
*scriptp = JS_CompileScriptForPrincipals(cx, target_obj, jsPrincipals, buf.get(),
|
||||
len, uriStr, 1);
|
||||
*scriptp = JS_CompileScriptForPrincipals(cx, target_obj, nsJSPrincipals::get(principal),
|
||||
buf.get(), len, uriStr, 1);
|
||||
}
|
||||
|
||||
JSPRINCIPALS_DROP(cx, jsPrincipals);
|
||||
|
||||
/* repent for our evil deeds */
|
||||
JS_SetErrorReporter(cx, er);
|
||||
|
||||
@ -204,7 +193,7 @@ mozJSSubScriptLoader::LoadSubScript(const nsAString& url,
|
||||
__LINE__, NS_LossyConvertUTF16toASCII(url).get());
|
||||
#endif
|
||||
|
||||
/* set mJSPrincipals if it's not here already */
|
||||
/* set the system principal if it's not here already */
|
||||
if (!mSystemPrincipal) {
|
||||
nsCOMPtr<nsIScriptSecurityManager> secman =
|
||||
do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID);
|
||||
|
@ -81,6 +81,7 @@
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsIXPCSecurityManager.h"
|
||||
#include "nsJSPrincipals.h"
|
||||
#include "xpcpublic.h"
|
||||
#ifdef XP_MACOSX
|
||||
#include "xpcshellMacUtils.h"
|
||||
@ -1739,11 +1740,13 @@ GetCurrentWorkingDirectory(nsAString& workingDirectory)
|
||||
}
|
||||
|
||||
static JSPrincipals *
|
||||
FindObjectPrincipals(JSContext *cx, JSObject *obj)
|
||||
FindObjectPrincipals(JSObject *obj)
|
||||
{
|
||||
return gJSPrincipals;
|
||||
}
|
||||
|
||||
static JSSecurityCallbacks shellSecurityCallbacks;
|
||||
|
||||
int
|
||||
main(int argc, char **argv, char **envp)
|
||||
{
|
||||
@ -1905,10 +1908,8 @@ main(int argc, char **argv, char **envp)
|
||||
fprintf(gErrFile, "+++ Failed to obtain SystemPrincipal from ScriptSecurityManager service.\n");
|
||||
} else {
|
||||
// fetch the JS principals and stick in a global
|
||||
rv = systemprincipal->GetJSPrincipals(cx, &gJSPrincipals);
|
||||
if (NS_FAILED(rv)) {
|
||||
fprintf(gErrFile, "+++ Failed to obtain JS principals from SystemPrincipal.\n");
|
||||
}
|
||||
gJSPrincipals = nsJSPrincipals::get(systemprincipal);
|
||||
JS_HoldPrincipals(gJSPrincipals);
|
||||
secman->SetSystemPrincipal(systemprincipal);
|
||||
}
|
||||
} else {
|
||||
@ -1916,10 +1917,11 @@ main(int argc, char **argv, char **envp)
|
||||
}
|
||||
}
|
||||
|
||||
JSSecurityCallbacks *cb = JS_GetRuntimeSecurityCallbacks(rt);
|
||||
NS_ASSERTION(cb, "We are assuming that nsScriptSecurityManager::Init() has been run");
|
||||
NS_ASSERTION(!cb->findObjectPrincipals, "Your pigeon is in my hole!");
|
||||
cb->findObjectPrincipals = FindObjectPrincipals;
|
||||
const JSSecurityCallbacks *scb = JS_GetSecurityCallbacks(rt);
|
||||
NS_ASSERTION(scb, "We are assuming that nsScriptSecurityManager::Init() has been run");
|
||||
shellSecurityCallbacks = *scb;
|
||||
shellSecurityCallbacks.findObjectPrincipals = FindObjectPrincipals;
|
||||
JS_SetSecurityCallbacks(rt, &shellSecurityCallbacks);
|
||||
|
||||
#ifdef TEST_TranslateThis
|
||||
nsCOMPtr<nsIXPCFunctionThisTranslator>
|
||||
@ -2009,7 +2011,7 @@ main(int argc, char **argv, char **envp)
|
||||
xpc->WrapJS(cx, glob, NS_GET_IID(nsIJSContextStack),
|
||||
(void**) getter_AddRefs(bogus));
|
||||
#endif
|
||||
JSPRINCIPALS_DROP(cx, gJSPrincipals);
|
||||
JS_DropPrincipals(rt, gJSPrincipals);
|
||||
JS_ClearScope(cx, glob);
|
||||
JS_GC(cx);
|
||||
JSContext *oldcx;
|
||||
|
@ -3437,14 +3437,18 @@ xpc_EvalInSandbox(JSContext *cx, JSObject *sandbox, const nsAString& source,
|
||||
NS_ASSERTION(sop, "Invalid sandbox passed");
|
||||
nsCOMPtr<nsIPrincipal> prin = sop->GetPrincipal();
|
||||
|
||||
JSPrincipals *jsPrincipals;
|
||||
|
||||
if (!prin ||
|
||||
NS_FAILED(prin->GetJSPrincipals(cx, &jsPrincipals)) ||
|
||||
!jsPrincipals) {
|
||||
if (!prin) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsCAutoString filenameBuf;
|
||||
if (!filename) {
|
||||
// Default to the spec of the principal.
|
||||
nsJSPrincipals::get(prin)->GetScriptLocation(filenameBuf);
|
||||
filename = filenameBuf.get();
|
||||
lineNo = 1;
|
||||
}
|
||||
|
||||
JSObject *callingScope;
|
||||
{
|
||||
JSAutoRequest req(cx);
|
||||
@ -3458,7 +3462,6 @@ xpc_EvalInSandbox(JSContext *cx, JSObject *sandbox, const nsAString& source,
|
||||
nsRefPtr<ContextHolder> sandcx = new ContextHolder(cx, sandbox);
|
||||
if (!sandcx || !sandcx->GetJSContext()) {
|
||||
JS_ReportError(cx, "Can't prepare context for evalInSandbox");
|
||||
JSPRINCIPALS_DROP(cx, jsPrincipals);
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
@ -3471,24 +3474,15 @@ xpc_EvalInSandbox(JSContext *cx, JSObject *sandbox, const nsAString& source,
|
||||
if (!stack->Push(sandcx->GetJSContext())) {
|
||||
JS_ReportError(cx,
|
||||
"Unable to initialize XPConnect with the sandbox context");
|
||||
JSPRINCIPALS_DROP(cx, jsPrincipals);
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
if (!filename) {
|
||||
// Default the filename to the codebase.
|
||||
filename = jsPrincipals->codebase;
|
||||
lineNo = 1;
|
||||
}
|
||||
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
{
|
||||
JSAutoRequest req(sandcx->GetJSContext());
|
||||
JSAutoEnterCompartment ac;
|
||||
jsval v;
|
||||
JSString *str = nsnull;
|
||||
|
||||
if (!ac.enter(sandcx->GetJSContext(), sandbox)) {
|
||||
if (stack)
|
||||
@ -3496,9 +3490,11 @@ xpc_EvalInSandbox(JSContext *cx, JSObject *sandbox, const nsAString& source,
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
jsval v;
|
||||
JSString *str = nsnull;
|
||||
JSBool ok =
|
||||
JS_EvaluateUCScriptForPrincipals(sandcx->GetJSContext(), sandbox,
|
||||
jsPrincipals,
|
||||
nsJSPrincipals::get(prin),
|
||||
reinterpret_cast<const jschar *>
|
||||
(PromiseFlatString(source).get()),
|
||||
source.Length(), filename, lineNo,
|
||||
@ -3571,8 +3567,6 @@ xpc_EvalInSandbox(JSContext *cx, JSObject *sandbox, const nsAString& source,
|
||||
if (stack)
|
||||
unused << stack->Pop();
|
||||
|
||||
JSPRINCIPALS_DROP(cx, jsPrincipals);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
@ -60,6 +60,8 @@
|
||||
#include "jsfriendapi.h"
|
||||
#include "js/MemoryMetrics.h"
|
||||
|
||||
#include "nsJSPrincipals.h"
|
||||
|
||||
#ifdef MOZ_CRASHREPORTER
|
||||
#include "nsExceptionHandler.h"
|
||||
#endif
|
||||
@ -1220,72 +1222,43 @@ XPCJSRuntime::~XPCJSRuntime()
|
||||
XPCPerThreadData::ShutDown();
|
||||
}
|
||||
|
||||
static void*
|
||||
GetCompartmentNameHelper(JSCompartment *c, bool getAddress)
|
||||
static void
|
||||
GetCompartmentName(JSCompartment *c, bool getAddress, nsCString &name)
|
||||
{
|
||||
nsCString* name = new nsCString();
|
||||
if (js::IsAtomsCompartment(c)) {
|
||||
name->AssignLiteral("atoms");
|
||||
name.AssignLiteral("atoms");
|
||||
} else if (JSPrincipals *principals = JS_GetCompartmentPrincipals(c)) {
|
||||
if (principals->codebase) {
|
||||
name->Assign(principals->codebase);
|
||||
nsJSPrincipals::get(principals)->GetScriptLocation(name);
|
||||
|
||||
// For system compartments we append the location, if there is one.
|
||||
// And we append the address if |getAddress| is true, so that
|
||||
// multiple system compartments (and there can be many) can be
|
||||
// distinguished.
|
||||
if (js::IsSystemCompartment(c)) {
|
||||
xpc::CompartmentPrivate *compartmentPrivate =
|
||||
static_cast<xpc::CompartmentPrivate*>(JS_GetCompartmentPrivate(c));
|
||||
if (compartmentPrivate &&
|
||||
!compartmentPrivate->location.IsEmpty()) {
|
||||
name->AppendLiteral(", ");
|
||||
name->Append(compartmentPrivate->location);
|
||||
}
|
||||
|
||||
if (getAddress) {
|
||||
// ample; 64-bit address max is 18 chars
|
||||
static const int maxLength = 31;
|
||||
nsPrintfCString address(maxLength, ", 0x%llx", PRUint64(c));
|
||||
name->Append(address);
|
||||
}
|
||||
// For system compartments we append the location, if there is one.
|
||||
// And we append the address if |getAddress| is true, so that
|
||||
// multiple system compartments (and there can be many) can be
|
||||
// distinguished.
|
||||
if (js::IsSystemCompartment(c)) {
|
||||
xpc::CompartmentPrivate *compartmentPrivate =
|
||||
static_cast<xpc::CompartmentPrivate*>(JS_GetCompartmentPrivate(c));
|
||||
if (compartmentPrivate && !compartmentPrivate->location.IsEmpty()) {
|
||||
name.AppendLiteral(", ");
|
||||
name.Append(compartmentPrivate->location);
|
||||
}
|
||||
|
||||
if (getAddress) {
|
||||
// ample; 64-bit address max is 18 chars
|
||||
const int maxLength = 31;
|
||||
nsPrintfCString address(maxLength, ", 0x%llx", PRUint64(c));
|
||||
name.Append(address);
|
||||
}
|
||||
|
||||
// A hack: replace forward slashes with '\\' so they aren't
|
||||
// treated as path separators. Users of the reporters
|
||||
// (such as about:memory) have to undo this change.
|
||||
name->ReplaceChar('/', '\\');
|
||||
} else {
|
||||
name->AssignLiteral("null-codebase");
|
||||
}
|
||||
|
||||
// A hack: replace forward slashes with '\\' so they aren't
|
||||
// treated as path separators. Users of the reporters
|
||||
// (such as about:memory) have to undo this change.
|
||||
name.ReplaceChar('/', '\\');
|
||||
} else {
|
||||
name->AssignLiteral("null-principal");
|
||||
name.AssignLiteral("null-principal");
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
static void*
|
||||
GetCompartmentNameAndAddress(JSRuntime *rt, JSCompartment *c)
|
||||
{
|
||||
return GetCompartmentNameHelper(c, /* get address = */true);
|
||||
}
|
||||
|
||||
namespace xpc {
|
||||
|
||||
void*
|
||||
GetCompartmentName(JSRuntime *rt, JSCompartment *c)
|
||||
{
|
||||
return GetCompartmentNameHelper(c, /* get address = */false);
|
||||
}
|
||||
|
||||
void
|
||||
DestroyCompartmentName(void *string)
|
||||
{
|
||||
delete static_cast<nsCString*>(string);
|
||||
}
|
||||
|
||||
} // namespace xpc
|
||||
|
||||
// We have per-compartment GC heap totals, so we can't put the total GC heap
|
||||
// size in the explicit allocations tree. But it's a useful figure, so put it
|
||||
// in the "others" list.
|
||||
@ -1404,9 +1377,12 @@ inline const nsCString
|
||||
MakePath(const nsACString &pathPrefix, const JS::CompartmentStats &cStats,
|
||||
const char (&reporterName)[N])
|
||||
{
|
||||
return pathPrefix + NS_LITERAL_CSTRING("compartment(") +
|
||||
*static_cast<nsCString*>(cStats.name) +
|
||||
NS_LITERAL_CSTRING(")/") + nsDependentCString(reporterName);
|
||||
const char *name = static_cast<char *>(cStats.extra);
|
||||
if (!name)
|
||||
name = "error while initializing compartment name";
|
||||
return pathPrefix + NS_LITERAL_CSTRING("compartment(") +
|
||||
nsDependentCString(name) + NS_LITERAL_CSTRING(")/") +
|
||||
nsDependentCString(reporterName);
|
||||
}
|
||||
|
||||
namespace mozilla {
|
||||
@ -1694,18 +1670,15 @@ class JSCompartmentsMultiReporter : public nsIMemoryMultiReporter
|
||||
|
||||
static void CompartmentCallback(JSRuntime *rt, void* data, JSCompartment *c)
|
||||
{
|
||||
// silently ignore OOM errors
|
||||
Paths *paths = static_cast<Paths *>(data);
|
||||
nsCString *name =
|
||||
static_cast<nsCString *>(xpc::GetCompartmentName(rt, c));
|
||||
nsCString path;
|
||||
if (js::IsSystemCompartment(c))
|
||||
path = NS_LITERAL_CSTRING("compartments/system/") + *name;
|
||||
else
|
||||
path = NS_LITERAL_CSTRING("compartments/user/") + *name;
|
||||
if (!paths->append(path))
|
||||
return; // silent failure, but it's very unlikely
|
||||
|
||||
xpc::DestroyCompartmentName(name);
|
||||
GetCompartmentName(c, /* getAddress = */ false, path);
|
||||
path.Insert(js::IsSystemCompartment(c)
|
||||
? NS_LITERAL_CSTRING("compartments/system/")
|
||||
: NS_LITERAL_CSTRING("compartments/user/"),
|
||||
0);
|
||||
paths->append(path);
|
||||
}
|
||||
|
||||
NS_IMETHOD CollectReports(nsIMemoryMultiReporterCallback *cb,
|
||||
@ -1745,6 +1718,23 @@ NS_IMPL_THREADSAFE_ISUPPORTS1(JSCompartmentsMultiReporter
|
||||
, nsIMemoryMultiReporter
|
||||
)
|
||||
|
||||
struct XPCJSRuntimeStats : public JS::RuntimeStats {
|
||||
XPCJSRuntimeStats()
|
||||
: JS::RuntimeStats(JsMallocSizeOf) { }
|
||||
|
||||
~XPCJSRuntimeStats() {
|
||||
for (size_t i = 0; i != compartmentStatsVector.length(); ++i)
|
||||
free(compartmentStatsVector[i].extra);
|
||||
}
|
||||
|
||||
virtual void initExtraCompartmentStats(JSCompartment *c,
|
||||
JS::CompartmentStats *cstats) MOZ_OVERRIDE {
|
||||
nsCAutoString name;
|
||||
GetCompartmentName(c, /* getAddress = */ true, name);
|
||||
cstats->extra = strdup(name.get());
|
||||
}
|
||||
};
|
||||
|
||||
class JSMemoryMultiReporter : public nsIMemoryMultiReporter
|
||||
{
|
||||
public:
|
||||
@ -1766,8 +1756,7 @@ public:
|
||||
// the callback. Separating these steps is important because the
|
||||
// callback may be a JS function, and executing JS while getting these
|
||||
// stats seems like a bad idea.
|
||||
JS::RuntimeStats rtStats(JsMallocSizeOf, GetCompartmentNameAndAddress,
|
||||
xpc::DestroyCompartmentName);
|
||||
XPCJSRuntimeStats rtStats;
|
||||
if (!JS::CollectRuntimeStats(xpcrt->GetJSRuntime(), &rtStats))
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
|
@ -1145,12 +1145,8 @@ CreateNewCompartment(JSContext *cx, JSClass *clasp, nsIPrincipal *principal,
|
||||
// of failure or give ownership to the compartment in case of success (in
|
||||
// that case it will be free'd in CompartmentCallback during GC).
|
||||
nsAutoPtr<xpc::CompartmentPrivate> priv_holder(priv);
|
||||
JSPrincipals *principals = nsnull;
|
||||
if (principal)
|
||||
principal->GetJSPrincipals(cx, &principals);
|
||||
JSObject *tempGlobal = JS_NewCompartmentAndGlobalObject(cx, clasp, principals);
|
||||
if (principals)
|
||||
JSPRINCIPALS_DROP(cx, principals);
|
||||
JSObject *tempGlobal =
|
||||
JS_NewCompartmentAndGlobalObject(cx, clasp, nsJSPrincipals::get(principal));
|
||||
|
||||
if (!tempGlobal)
|
||||
return false;
|
||||
|
@ -222,9 +222,6 @@ bool Base64Decode(JSContext *cx, JS::Value val, JS::Value *out);
|
||||
bool StringToJsval(JSContext *cx, nsAString &str, JS::Value *rval);
|
||||
bool NonVoidStringToJsval(JSContext *cx, nsAString &str, JS::Value *rval);
|
||||
|
||||
void *GetCompartmentName(JSRuntime *rt, JSCompartment *c);
|
||||
void DestroyCompartmentName(void *string);
|
||||
|
||||
#ifdef DEBUG
|
||||
void DumpJSHeap(FILE* file);
|
||||
#endif
|
||||
|
@ -61,8 +61,7 @@ namespace xpc {
|
||||
nsIPrincipal *
|
||||
GetCompartmentPrincipal(JSCompartment *compartment)
|
||||
{
|
||||
JSPrincipals *prin = JS_GetCompartmentPrincipals(compartment);
|
||||
return prin ? static_cast<nsJSPrincipals *>(prin)->nsIPrincipalPtr : nsnull;
|
||||
return nsJSPrincipals::get(JS_GetCompartmentPrincipals(compartment));
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -2164,7 +2164,6 @@ NS_IMETHODIMP
|
||||
nsCryptoRunnable::Run()
|
||||
{
|
||||
nsNSSShutDownPreventionLock locker;
|
||||
JSPrincipals *principals;
|
||||
JSContext *cx = m_args->m_cx;
|
||||
|
||||
JSAutoRequest ar(cx);
|
||||
@ -2174,29 +2173,20 @@ nsCryptoRunnable::Run()
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsresult rv = m_args->m_principals->GetJSPrincipals(cx, &principals);
|
||||
if (NS_FAILED(rv))
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
// make sure the right context is on the stack. must not return w/out popping
|
||||
nsCOMPtr<nsIJSContextStack> stack(do_GetService("@mozilla.org/js/xpc/ContextStack;1"));
|
||||
if (!stack || NS_FAILED(stack->Push(cx))) {
|
||||
JSPRINCIPALS_DROP(cx, principals);
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
jsval retval;
|
||||
if (JS_EvaluateScriptForPrincipals(cx, m_args->m_scope, principals,
|
||||
m_args->m_jsCallback,
|
||||
strlen(m_args->m_jsCallback),
|
||||
nsnull, 0,
|
||||
&retval) != JS_TRUE) {
|
||||
rv = NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
JSBool ok =
|
||||
JS_EvaluateScriptForPrincipals(cx, m_args->m_scope,
|
||||
nsJSPrincipals::get(m_args->m_principals),
|
||||
m_args->m_jsCallback,
|
||||
strlen(m_args->m_jsCallback),
|
||||
nsnull, 0, nsnull);
|
||||
stack->Pop(nsnull);
|
||||
JSPRINCIPALS_DROP(cx, principals);
|
||||
return rv;
|
||||
return ok ? NS_OK : NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
//Quick helper function to check if a newly issued cert
|
||||
|
Loading…
Reference in New Issue
Block a user