mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Fix bug 657267. r=bz
This commit is contained in:
parent
a572e3fb87
commit
fbea73993b
@ -52,7 +52,7 @@ interface nsIContentSecurityPolicy;
|
||||
[ptr] native JSContext(JSContext);
|
||||
[ptr] native JSPrincipals(JSPrincipals);
|
||||
|
||||
[scriptable, uuid(799ab95c-0038-4e0f-b705-74c21f185bb5)]
|
||||
[scriptable, uuid(B406A2DB-E547-4C95-B8E2-AD09ECB54CE0)]
|
||||
interface nsIPrincipal : nsISerializable
|
||||
{
|
||||
/**
|
||||
@ -86,6 +86,11 @@ interface nsIPrincipal : nsISerializable
|
||||
*/
|
||||
boolean equals(in nsIPrincipal other);
|
||||
|
||||
/**
|
||||
* Like equals, but doesn't take document.domain changes into account.
|
||||
*/
|
||||
boolean equalsIgnoringDomain(in nsIPrincipal other);
|
||||
|
||||
/**
|
||||
* Returns a hash value for the principal.
|
||||
*/
|
||||
|
@ -131,6 +131,9 @@ protected:
|
||||
const nsACString& aPrettyName,
|
||||
nsISupports* aCert);
|
||||
|
||||
// Checks whether this principal's certificate equals aOther's.
|
||||
PRBool CertificateEquals(nsIPrincipal *aOther);
|
||||
|
||||
// Keep this is a pointer, even though it may slightly increase the
|
||||
// cost of keeping a certificate, this is a good tradeoff though since
|
||||
// it is very rare that we actually have a certificate.
|
||||
|
@ -162,6 +162,12 @@ nsNullPrincipal::Equals(nsIPrincipal *aOther, PRBool *aResult)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNullPrincipal::EqualsIgnoringDomain(nsIPrincipal *aOther, PRBool *aResult)
|
||||
{
|
||||
return Equals(aOther, aResult);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNullPrincipal::GetHashValue(PRUint32 *aResult)
|
||||
{
|
||||
|
@ -309,42 +309,52 @@ nsPrincipal::SetSecurityPolicy(void* aSecurityPolicy)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsPrincipal::CertificateEquals(nsIPrincipal *aOther)
|
||||
{
|
||||
PRBool otherHasCert;
|
||||
aOther->GetHasCertificate(&otherHasCert);
|
||||
if (otherHasCert != (mCert != nsnull)) {
|
||||
// One has a cert while the other doesn't. Not equal.
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
if (!mCert)
|
||||
return PR_TRUE;
|
||||
|
||||
nsCAutoString str;
|
||||
aOther->GetFingerprint(str);
|
||||
if (!str.Equals(mCert->fingerprint))
|
||||
return PR_FALSE;
|
||||
|
||||
// If either subject name is empty, just let the result stand (so that
|
||||
// nsScriptSecurityManager::SetCanEnableCapability works), but if they're
|
||||
// both non-empty, only claim equality if they're equal.
|
||||
if (!mCert->subjectName.IsEmpty()) {
|
||||
// Check the other principal's subject name
|
||||
aOther->GetSubjectName(str);
|
||||
return str.Equals(mCert->subjectName) || str.IsEmpty();
|
||||
}
|
||||
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPrincipal::Equals(nsIPrincipal *aOther, PRBool *aResult)
|
||||
{
|
||||
*aResult = PR_FALSE;
|
||||
|
||||
if (!aOther) {
|
||||
NS_WARNING("Need a principal to compare this to!");
|
||||
*aResult = PR_FALSE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (this != aOther) {
|
||||
PRBool otherHasCert;
|
||||
aOther->GetHasCertificate(&otherHasCert);
|
||||
if (otherHasCert != (mCert != nsnull)) {
|
||||
// One has a cert while the other doesn't. Not equal.
|
||||
if (!CertificateEquals(aOther)) {
|
||||
*aResult = PR_FALSE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (mCert) {
|
||||
nsCAutoString str;
|
||||
aOther->GetFingerprint(str);
|
||||
*aResult = str.Equals(mCert->fingerprint);
|
||||
|
||||
// If either subject name is empty, just let the result stand (so that
|
||||
// nsScriptSecurityManager::SetCanEnableCapability works), but if they're
|
||||
// both non-empty, only claim equality if they're equal.
|
||||
if (*aResult && !mCert->subjectName.IsEmpty()) {
|
||||
// Check the other principal's subject name
|
||||
aOther->GetSubjectName(str);
|
||||
*aResult = str.Equals(mCert->subjectName) || str.IsEmpty();
|
||||
}
|
||||
|
||||
if (!*aResult) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// If either principal has no URI, it's the saved principal from
|
||||
// preferences; in that case, test true. Do NOT test true if the two
|
||||
// principals have URIs with different codebases.
|
||||
@ -356,6 +366,7 @@ nsPrincipal::Equals(nsIPrincipal *aOther, PRBool *aResult)
|
||||
}
|
||||
|
||||
if (!otherURI || !mCodebase) {
|
||||
*aResult = PR_TRUE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -373,6 +384,34 @@ nsPrincipal::Equals(nsIPrincipal *aOther, PRBool *aResult)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPrincipal::EqualsIgnoringDomain(nsIPrincipal *aOther, PRBool *aResult)
|
||||
{
|
||||
if (this == aOther) {
|
||||
*aResult = PR_TRUE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
*aResult = PR_FALSE;
|
||||
if (!CertificateEquals(aOther)) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIURI> otherURI;
|
||||
nsresult rv = aOther->GetURI(getter_AddRefs(otherURI));
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_ASSERTION(mCodebase,
|
||||
"shouldn't be calling this on principals from preferences");
|
||||
|
||||
// Compare codebases.
|
||||
*aResult = nsScriptSecurityManager::SecurityCompareURIs(mCodebase,
|
||||
otherURI);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPrincipal::Subsumes(nsIPrincipal *aOther, PRBool *aResult)
|
||||
{
|
||||
|
@ -110,6 +110,12 @@ nsSystemPrincipal::Equals(nsIPrincipal *other, PRBool *result)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSystemPrincipal::EqualsIgnoringDomain(nsIPrincipal *other, PRBool *result)
|
||||
{
|
||||
return Equals(other, result);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSystemPrincipal::Subsumes(nsIPrincipal *other, PRBool *result)
|
||||
{
|
||||
|
@ -1039,17 +1039,12 @@ xpc_CreateGlobalObject(JSContext *cx, JSClass *clasp,
|
||||
NS_ABORT_IF_FALSE(NS_IsMainThread(), "using a principal off the main thread?");
|
||||
NS_ABORT_IF_FALSE(principal, "bad key");
|
||||
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
nsresult rv = principal->GetURI(getter_AddRefs(uri));
|
||||
if(NS_FAILED(rv))
|
||||
return UnexpectedFailure(rv);
|
||||
|
||||
XPCCompartmentMap& map = nsXPConnect::GetRuntimeInstance()->GetCompartmentMap();
|
||||
xpc::PtrAndPrincipalHashKey key(ptr, uri);
|
||||
xpc::PtrAndPrincipalHashKey key(ptr, principal);
|
||||
if(!map.Get(&key, compartment))
|
||||
{
|
||||
xpc::PtrAndPrincipalHashKey *priv_key =
|
||||
new xpc::PtrAndPrincipalHashKey(ptr, uri);
|
||||
new xpc::PtrAndPrincipalHashKey(ptr, principal);
|
||||
xpc::CompartmentPrivate *priv =
|
||||
new xpc::CompartmentPrivate(priv_key, wantXrays, NS_IsMainThread());
|
||||
if(!CreateNewCompartment(cx, clasp, principal, priv,
|
||||
|
@ -1,4 +1,5 @@
|
||||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* vim: set ts=4 sw=4 et tw=79:
|
||||
*
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
@ -47,14 +48,19 @@
|
||||
PRBool
|
||||
xpc::PtrAndPrincipalHashKey::KeyEquals(const PtrAndPrincipalHashKey* aKey) const
|
||||
{
|
||||
if(aKey->mPtr != mPtr)
|
||||
return PR_FALSE;
|
||||
if(aKey->mPtr != mPtr)
|
||||
return PR_FALSE;
|
||||
if(aKey->mPrincipal == mPrincipal)
|
||||
return PR_TRUE;
|
||||
|
||||
if(!mURI || !aKey->mURI)
|
||||
return mURI == aKey->mURI;
|
||||
PRBool equals;
|
||||
if(NS_FAILED(mPrincipal->EqualsIgnoringDomain(aKey->mPrincipal, &equals)))
|
||||
{
|
||||
NS_ERROR("we failed, guessing!");
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
nsIScriptSecurityManager *ssm = nsXPConnect::gScriptSecurityManager;
|
||||
return !ssm || NS_SUCCEEDED(ssm->CheckSameOriginURI(mURI, aKey->mURI, PR_FALSE));
|
||||
return equals;
|
||||
}
|
||||
|
||||
inline void
|
||||
|
@ -247,17 +247,20 @@ class PtrAndPrincipalHashKey : public PLDHashEntryHdr
|
||||
typedef const PtrAndPrincipalHashKey *KeyTypePointer;
|
||||
|
||||
PtrAndPrincipalHashKey(const PtrAndPrincipalHashKey *aKey)
|
||||
: mPtr(aKey->mPtr), mURI(aKey->mURI), mSavedHash(aKey->mSavedHash)
|
||||
: mPtr(aKey->mPtr), mPrincipal(aKey->mPrincipal),
|
||||
mSavedHash(aKey->mSavedHash)
|
||||
{
|
||||
MOZ_COUNT_CTOR(PtrAndPrincipalHashKey);
|
||||
}
|
||||
|
||||
PtrAndPrincipalHashKey(nsISupports *aPtr, nsIURI *aURI)
|
||||
: mPtr(aPtr), mURI(aURI)
|
||||
PtrAndPrincipalHashKey(nsISupports *aPtr, nsIPrincipal *aPrincipal)
|
||||
: mPtr(aPtr), mPrincipal(aPrincipal)
|
||||
{
|
||||
MOZ_COUNT_CTOR(PtrAndPrincipalHashKey);
|
||||
mSavedHash = mURI
|
||||
? NS_SecurityHashURI(mURI)
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
aPrincipal->GetURI(getter_AddRefs(uri));
|
||||
mSavedHash = uri
|
||||
? NS_SecurityHashURI(uri)
|
||||
: (NS_PTR_TO_UINT32(mPtr.get()) >> 2);
|
||||
}
|
||||
|
||||
@ -285,7 +288,7 @@ class PtrAndPrincipalHashKey : public PLDHashEntryHdr
|
||||
|
||||
protected:
|
||||
nsCOMPtr<nsISupports> mPtr;
|
||||
nsCOMPtr<nsIURI> mURI;
|
||||
nsCOMPtr<nsIPrincipal> mPrincipal;
|
||||
|
||||
// During shutdown, when we GC, we need to remove these keys from the hash
|
||||
// table. However, computing the saved hash, NS_SecurityHashURI calls back
|
||||
|
@ -91,6 +91,8 @@ _TEST_FILES = bug500931_helper.html \
|
||||
test_bug636097.html \
|
||||
test_bug650273.html \
|
||||
file_bug650273.html \
|
||||
test_bug657267.html \
|
||||
bug657267.jar \
|
||||
$(NULL)
|
||||
|
||||
#test_bug484107.html \
|
||||
|
BIN
js/src/xpconnect/tests/mochitest/bug657267.jar
Normal file
BIN
js/src/xpconnect/tests/mochitest/bug657267.jar
Normal file
Binary file not shown.
42
js/src/xpconnect/tests/mochitest/test_bug657267.html
Normal file
42
js/src/xpconnect/tests/mochitest/test_bug657267.html
Normal file
@ -0,0 +1,42 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=657267
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 657267</title>
|
||||
<script type="application/javascript" src="/MochiKit/packed.js"></script>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=657267">Mozilla Bug 657267</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
|
||||
/** Test for Bug 657267 **/
|
||||
function go() {
|
||||
var win = $('ifr').contentWindow;
|
||||
try {
|
||||
win.a();
|
||||
var thrown = false;
|
||||
} catch (e) {
|
||||
thrown = /Permission denied/i.test(e);
|
||||
}
|
||||
ok(thrown, "Should have thrown");
|
||||
}
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
|
||||
<iframe src="jar:http://mochi.test:8888/tests/js/src/xpconnect/tests/mochitest/bug657267.jar!/file_bug657267.html"
|
||||
id="ifr"
|
||||
onload="go()">
|
||||
</iframe>
|
||||
</body>
|
||||
</html>
|
@ -72,17 +72,14 @@ AccessCheck::isSameOrigin(JSCompartment *a, JSCompartment *b)
|
||||
if (!aprin || !bprin)
|
||||
return true;
|
||||
|
||||
nsCOMPtr<nsIURI> auri;
|
||||
aprin->GetURI(getter_AddRefs(auri));
|
||||
PRBool equals;
|
||||
nsresult rv = aprin->EqualsIgnoringDomain(bprin, &equals);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_ERROR("unable to ask about equality");
|
||||
return false;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIURI> buri;
|
||||
bprin->GetURI(getter_AddRefs(buri));
|
||||
|
||||
if (!auri || !buri)
|
||||
return aprin == bprin;
|
||||
|
||||
nsIScriptSecurityManager *ssm = XPCWrapper::GetSecurityManager();
|
||||
return !ssm || NS_SUCCEEDED(ssm->CheckSameOriginURI(auri, buri, PR_FALSE));
|
||||
return equals;
|
||||
}
|
||||
|
||||
bool
|
||||
|
Loading…
Reference in New Issue
Block a user