mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 777072 - 3/7 - Update nsHostTable and nsHostEntry to make them aware of new security model. r=sicking,jlebar
This commit is contained in:
parent
101f5213c1
commit
ede8f880d1
@ -389,6 +389,8 @@ function runTest() {
|
||||
checkIFrame(this, data);
|
||||
};
|
||||
iframe.addChild = function() {
|
||||
SpecialPowers.addPermission("browser", true, iframe.contentDocument);
|
||||
|
||||
var childFrame = document.createElement('iframe');
|
||||
|
||||
if (data.child.app) {
|
||||
@ -429,7 +431,6 @@ function runTest() {
|
||||
|
||||
var gTestRunner = runTest();
|
||||
|
||||
SpecialPowers.addPermission("browser", true, "http://example.org");
|
||||
SpecialPowers.pushPrefEnv({'set':[["dom.mozBrowserFramesEnabled", true]]},
|
||||
function() { gTestRunner.next(); });
|
||||
|
||||
|
@ -18,6 +18,11 @@ function runTest() {
|
||||
browserElementTestHelpers.setEnabledPref(true);
|
||||
browserElementTestHelpers.addPermission();
|
||||
|
||||
var principal = SpecialPowers.wrap(SpecialPowers.getNodePrincipal(document));
|
||||
SpecialPowers.addPermission("browser", true, { url: SpecialPowers.wrap(principal.URI).spec,
|
||||
appId: principal.appId,
|
||||
isInBrowserElement: true });
|
||||
|
||||
iframe = document.createElement('iframe');
|
||||
iframe.mozbrowser = true;
|
||||
|
||||
@ -55,6 +60,12 @@ function finish() {
|
||||
// expected, but if we don't remove our listener, then we'll end up causing
|
||||
// the /next/ test to fail!
|
||||
iframe.removeEventListener('mozbrowsershowmodalprompt', checkMessage);
|
||||
|
||||
var principal = SpecialPowers.wrap(SpecialPowers.getNodePrincipal(document));
|
||||
SpecialPowers.removePermission("browser", { url: SpecialPowers.wrap(principal.URI).spec,
|
||||
appId: principal.appId,
|
||||
isInBrowserElement: true });
|
||||
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
|
@ -12,6 +12,11 @@ function runTest() {
|
||||
browserElementTestHelpers.setEnabledPref(true);
|
||||
browserElementTestHelpers.addPermission();
|
||||
|
||||
var principal = SpecialPowers.wrap(SpecialPowers.getNodePrincipal(document));
|
||||
SpecialPowers.addPermission("browser", true, { url: SpecialPowers.wrap(principal.URI).spec,
|
||||
appId: principal.appId,
|
||||
isInBrowserElement: true });
|
||||
|
||||
var iframe = document.createElement('iframe');
|
||||
iframe.mozbrowser = true;
|
||||
|
||||
@ -35,7 +40,7 @@ function runTest() {
|
||||
SimpleTest.executeSoon(function() {
|
||||
SimpleTest.executeSoon(function() {
|
||||
SimpleTest.executeSoon(function() {
|
||||
SimpleTest.finish();
|
||||
finish();
|
||||
});
|
||||
});
|
||||
});
|
||||
@ -50,4 +55,13 @@ function runTest() {
|
||||
document.body.appendChild(iframe);
|
||||
}
|
||||
|
||||
function finish() {
|
||||
var principal = SpecialPowers.wrap(SpecialPowers.getNodePrincipal(document));
|
||||
SpecialPowers.removePermission("browser", { url: SpecialPowers.wrap(principal.URI).spec,
|
||||
appId: principal.appId,
|
||||
isInBrowserElement: true });
|
||||
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
runTest();
|
||||
|
@ -71,28 +71,6 @@ ChildProcess()
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define PL_ARENA_CONST_ALIGN_MASK 3
|
||||
#include "plarena.h"
|
||||
|
||||
static PLArenaPool *gHostArena = nullptr;
|
||||
|
||||
// making sHostArena 512b for nice allocation
|
||||
// growing is quite cheap
|
||||
#define HOST_ARENA_SIZE 512
|
||||
|
||||
// equivalent to strdup() - does no error checking,
|
||||
// we're assuming we're only called with a valid pointer
|
||||
static char *
|
||||
ArenaStrDup(const char* str, PLArenaPool* aArena)
|
||||
{
|
||||
void* mem;
|
||||
const uint32_t size = strlen(str) + 1;
|
||||
PL_ARENA_ALLOCATE(mem, aArena, size);
|
||||
if (mem)
|
||||
memcpy(mem, str, size);
|
||||
return static_cast<char*>(mem);
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
nsresult
|
||||
@ -109,22 +87,34 @@ GetPrincipalForHost(const nsACString& aHost, nsIPrincipal** aPrincipal)
|
||||
return secMan->GetNoAppCodebasePrincipal(uri, aPrincipal);
|
||||
}
|
||||
|
||||
nsresult
|
||||
GetHostForPrincipal(nsIPrincipal* aPrincipal, nsACString& aHost)
|
||||
{
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
nsresult rv = aPrincipal->GetURI(getter_AddRefs(uri));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
uri = NS_GetInnermostURI(uri);
|
||||
NS_ENSURE_TRUE(uri, NS_ERROR_FAILURE);
|
||||
|
||||
rv = uri->GetAsciiHost(aHost);
|
||||
if (NS_FAILED(rv) || aHost.IsEmpty()) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
nsHostEntry::nsHostEntry(const char* aHost)
|
||||
{
|
||||
mHost = ArenaStrDup(aHost, gHostArena);
|
||||
}
|
||||
|
||||
// XXX this can fail on OOM
|
||||
nsHostEntry::nsHostEntry(const nsHostEntry& toCopy)
|
||||
: mHost(toCopy.mHost)
|
||||
, mPermissions(toCopy.mPermissions)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
nsPermissionManager::PermissionKey::PermissionKey(nsIPrincipal* aPrincipal)
|
||||
{
|
||||
MOZ_ALWAYS_TRUE(NS_SUCCEEDED(GetHostForPrincipal(aPrincipal, mHost)));
|
||||
MOZ_ALWAYS_TRUE(NS_SUCCEEDED(aPrincipal->GetAppId(&mAppId)));
|
||||
MOZ_ALWAYS_TRUE(NS_SUCCEEDED(aPrincipal->GetIsInBrowserElement(&mIsInBrowserElement)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple callback used by |AsyncClose| to trigger a treatment once
|
||||
@ -287,7 +277,7 @@ nsPermissionManager::Init()
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
mHostTable.Init();
|
||||
mPermissionTable.Init();
|
||||
|
||||
mObserverService = do_GetService("@mozilla.org/observer-service;1", &rv);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
@ -558,12 +548,8 @@ nsPermissionManager::AddInternal(nsIPrincipal* aPrincipal,
|
||||
NotifyOperationType aNotifyOperation,
|
||||
DBOperationType aDBOperation)
|
||||
{
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
nsresult rv = aPrincipal->GetURI(getter_AddRefs(uri));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCAutoString host;
|
||||
rv = GetHost(uri, host);
|
||||
nsresult rv = GetHostForPrincipal(aPrincipal, host);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (!IsChildProcess()) {
|
||||
@ -580,23 +566,17 @@ nsPermissionManager::AddInternal(nsIPrincipal* aPrincipal,
|
||||
}
|
||||
}
|
||||
|
||||
if (!gHostArena) {
|
||||
gHostArena = new PLArenaPool;
|
||||
if (!gHostArena)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
PL_INIT_ARENA_POOL(gHostArena, "PermissionHostArena", HOST_ARENA_SIZE);
|
||||
}
|
||||
|
||||
// look up the type index
|
||||
int32_t typeIndex = GetTypeIndex(aType.get(), true);
|
||||
NS_ENSURE_TRUE(typeIndex != -1, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
// When an entry already exists, PutEntry will return that, instead
|
||||
// of adding a new one
|
||||
nsHostEntry *entry = mHostTable.PutEntry(host.get());
|
||||
nsRefPtr<PermissionKey> key = new PermissionKey(aPrincipal);
|
||||
PermissionHashKey* entry = mPermissionTable.PutEntry(key);
|
||||
if (!entry) return NS_ERROR_FAILURE;
|
||||
if (!entry->GetKey()) {
|
||||
mHostTable.RawRemoveEntry(entry);
|
||||
mPermissionTable.RawRemoveEntry(entry);
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
@ -610,7 +590,7 @@ nsPermissionManager::AddInternal(nsIPrincipal* aPrincipal,
|
||||
op = eOperationAdding;
|
||||
|
||||
} else {
|
||||
nsPermissionEntry oldPermissionEntry = entry->GetPermissions()[index];
|
||||
PermissionEntry oldPermissionEntry = entry->GetPermissions()[index];
|
||||
|
||||
// remove the permission if the permission is UNKNOWN, update the
|
||||
// permission if its value or expire type have changed OR if the time has
|
||||
@ -648,7 +628,7 @@ nsPermissionManager::AddInternal(nsIPrincipal* aPrincipal,
|
||||
id = aID;
|
||||
}
|
||||
|
||||
entry->GetPermissions().AppendElement(nsPermissionEntry(typeIndex, aPermission, id, aExpireType, aExpireTime));
|
||||
entry->GetPermissions().AppendElement(PermissionEntry(id, typeIndex, aPermission, aExpireType, aExpireTime));
|
||||
|
||||
if (aDBOperation == eWriteToDB && aExpireType != nsIPermissionManager::EXPIRE_SESSION)
|
||||
UpdateDB(op, mStmtInsert, id, host, aType, aPermission, aExpireType, aExpireTime);
|
||||
@ -667,13 +647,13 @@ nsPermissionManager::AddInternal(nsIPrincipal* aPrincipal,
|
||||
|
||||
case eOperationRemoving:
|
||||
{
|
||||
nsPermissionEntry oldPermissionEntry = entry->GetPermissions()[index];
|
||||
PermissionEntry oldPermissionEntry = entry->GetPermissions()[index];
|
||||
id = oldPermissionEntry.mID;
|
||||
entry->GetPermissions().RemoveElementAt(index);
|
||||
|
||||
// If no more types are present, remove the entry
|
||||
if (entry->GetPermissions().IsEmpty())
|
||||
mHostTable.RawRemoveEntry(entry);
|
||||
mPermissionTable.RawRemoveEntry(entry);
|
||||
|
||||
if (aDBOperation == eWriteToDB)
|
||||
UpdateDB(op, mStmtDelete, id, EmptyCString(), EmptyCString(), 0,
|
||||
@ -888,7 +868,7 @@ nsPermissionManager::CommonTestPermission(nsIPrincipal* aPrincipal,
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCAutoString host;
|
||||
rv = GetHost(uri, host);
|
||||
rv = GetHostForPrincipal(aPrincipal, host);
|
||||
|
||||
// No host doesn't mean an error. Just return the default. Unless this is
|
||||
// a file uri. In that case use a magic host.
|
||||
@ -909,38 +889,64 @@ nsPermissionManager::CommonTestPermission(nsIPrincipal* aPrincipal,
|
||||
// so just return NS_OK
|
||||
if (typeIndex == -1) return NS_OK;
|
||||
|
||||
nsHostEntry *entry = GetHostEntry(host, typeIndex, aExactHostMatch);
|
||||
if (entry)
|
||||
uint32_t appId;
|
||||
rv = aPrincipal->GetAppId(&appId);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
bool isInBrowserElement;
|
||||
rv = aPrincipal->GetIsInBrowserElement(&isInBrowserElement);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
PermissionHashKey* entry = GetPermissionHashKey(host, appId, isInBrowserElement,
|
||||
typeIndex, aExactHostMatch);
|
||||
if (entry) {
|
||||
*aPermission = entry->GetPermission(typeIndex).mPermission;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Get hostentry for given host string and permission type.
|
||||
// walk up the domain if needed.
|
||||
// return null if nothing found.
|
||||
// Returns PermissionHashKey for a given { host, appId, isInBrowserElement } tuple.
|
||||
// This is not simply using PermissionKey because we will walk-up domains in
|
||||
// case of |host| contains sub-domains.
|
||||
// Returns null if nothing found.
|
||||
// Also accepts host on the format "<foo>". This will perform an exact match
|
||||
// lookup as the string doesn't contain any dots.
|
||||
nsHostEntry *
|
||||
nsPermissionManager::GetHostEntry(const nsAFlatCString &aHost,
|
||||
uint32_t aType,
|
||||
bool aExactHostMatch)
|
||||
nsPermissionManager::PermissionHashKey*
|
||||
nsPermissionManager::GetPermissionHashKey(const nsACString& aHost,
|
||||
uint32_t aAppId,
|
||||
bool aIsInBrowserElement,
|
||||
uint32_t aType,
|
||||
bool aExactHostMatch)
|
||||
{
|
||||
uint32_t offset = 0;
|
||||
nsHostEntry *entry;
|
||||
PermissionHashKey* entry;
|
||||
int64_t now = PR_Now() / 1000;
|
||||
|
||||
do {
|
||||
entry = mHostTable.GetEntry(aHost.get() + offset);
|
||||
nsRefPtr<PermissionKey> key = new PermissionKey(Substring(aHost, offset), aAppId, aIsInBrowserElement);
|
||||
entry = mPermissionTable.GetEntry(key);
|
||||
if (entry) {
|
||||
nsPermissionEntry permEntry = entry->GetPermission(aType);
|
||||
PermissionEntry permEntry = entry->GetPermission(aType);
|
||||
|
||||
// if the entry is expired, remove and keep looking for others.
|
||||
if (permEntry.mExpireType == nsIPermissionManager::EXPIRE_TIME &&
|
||||
permEntry.mExpireTime <= now)
|
||||
Remove(aHost, mTypeArray[aType].get());
|
||||
else if (permEntry.mPermission != nsIPermissionManager::UNKNOWN_ACTION)
|
||||
permEntry.mExpireTime <= now) {
|
||||
nsCOMPtr<nsIPrincipal> principal;
|
||||
nsIScriptSecurityManager* secMan = nsContentUtils::GetSecurityManager();
|
||||
MOZ_ASSERT(secMan, "No security manager!?");
|
||||
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
NS_NewURI(getter_AddRefs(uri), NS_LITERAL_CSTRING("http://") + aHost);
|
||||
|
||||
if (NS_FAILED(secMan->GetAppCodebasePrincipal(uri, aAppId, aIsInBrowserElement, getter_AddRefs(principal)))) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RemoveFromPrincipal(principal, mTypeArray[aType].get());
|
||||
} else if (permEntry.mPermission != nsIPermissionManager::UNKNOWN_ACTION) {
|
||||
break;
|
||||
}
|
||||
|
||||
// reset entry, to be able to return null on failure
|
||||
entry = nullptr;
|
||||
@ -968,14 +974,14 @@ struct nsGetEnumeratorData
|
||||
};
|
||||
|
||||
static PLDHashOperator
|
||||
AddPermissionsToList(nsHostEntry *entry, void *arg)
|
||||
AddPermissionsToList(nsPermissionManager::PermissionHashKey* entry, void *arg)
|
||||
{
|
||||
nsGetEnumeratorData *data = static_cast<nsGetEnumeratorData *>(arg);
|
||||
|
||||
for (uint32_t i = 0; i < entry->GetPermissions().Length(); ++i) {
|
||||
nsPermissionEntry &permEntry = entry->GetPermissions()[i];
|
||||
nsPermissionManager::PermissionEntry& permEntry = entry->GetPermissions()[i];
|
||||
|
||||
nsPermission *perm = new nsPermission(entry->GetHost(),
|
||||
nsPermission *perm = new nsPermission(entry->GetKey()->mHost,
|
||||
data->types->ElementAt(permEntry.mType),
|
||||
permEntry.mPermission,
|
||||
permEntry.mExpireType,
|
||||
@ -993,7 +999,7 @@ NS_IMETHODIMP nsPermissionManager::GetEnumerator(nsISimpleEnumerator **aEnum)
|
||||
nsCOMArray<nsIPermission> array;
|
||||
nsGetEnumeratorData data(&array, &mTypeArray);
|
||||
|
||||
mHostTable.EnumerateEntries(AddPermissionsToList, &data);
|
||||
mPermissionTable.EnumerateEntries(AddPermissionsToList, &data);
|
||||
|
||||
return NS_NewArrayEnumerator(aEnum, array);
|
||||
}
|
||||
@ -1031,12 +1037,8 @@ nsPermissionManager::RemoveAllFromMemory()
|
||||
{
|
||||
mLargestID = 0;
|
||||
mTypeArray.Clear();
|
||||
mHostTable.Clear();
|
||||
if (gHostArena) {
|
||||
PL_FinishArenaPool(gHostArena);
|
||||
delete gHostArena;
|
||||
}
|
||||
gHostArena = nullptr;
|
||||
mPermissionTable.Clear();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -1257,20 +1259,6 @@ nsPermissionManager::NormalizeToACE(nsCString &aHost)
|
||||
return mIDNService->ConvertUTF8toACE(aHost, aHost);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsPermissionManager::GetHost(nsIURI *aURI, nsACString &aResult)
|
||||
{
|
||||
nsCOMPtr<nsIURI> innerURI = NS_GetInnermostURI(aURI);
|
||||
if (!innerURI) return NS_ERROR_FAILURE;
|
||||
|
||||
nsresult rv = innerURI->GetAsciiHost(aResult);
|
||||
|
||||
if (NS_FAILED(rv) || aResult.IsEmpty())
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsPermissionManager::UpdateDB(OperationType aOp,
|
||||
mozIStorageStatement* aStmt,
|
||||
|
@ -16,6 +16,8 @@
|
||||
#include "nsTArray.h"
|
||||
#include "nsString.h"
|
||||
#include "nsPermission.h"
|
||||
#include "nsHashKeys.h"
|
||||
#include "nsAutoPtr.h"
|
||||
|
||||
class nsIPermission;
|
||||
class nsIIDNService;
|
||||
@ -24,107 +26,132 @@ class mozIStorageStatement;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class nsPermissionEntry
|
||||
{
|
||||
public:
|
||||
nsPermissionEntry(uint32_t aType, uint32_t aPermission, int64_t aID,
|
||||
uint32_t aExpireType, int64_t aExpireTime)
|
||||
: mType(aType)
|
||||
, mPermission(aPermission)
|
||||
, mID(aID)
|
||||
, mExpireType(aExpireType)
|
||||
, mExpireTime(aExpireTime) {}
|
||||
|
||||
uint32_t mType;
|
||||
uint32_t mPermission;
|
||||
int64_t mID;
|
||||
uint32_t mExpireType;
|
||||
int64_t mExpireTime;
|
||||
};
|
||||
|
||||
class nsHostEntry : public PLDHashEntryHdr
|
||||
{
|
||||
public:
|
||||
// Hash methods
|
||||
typedef const char* KeyType;
|
||||
typedef const char* KeyTypePointer;
|
||||
|
||||
nsHostEntry(const char* aHost);
|
||||
nsHostEntry(const nsHostEntry& toCopy);
|
||||
|
||||
~nsHostEntry()
|
||||
{
|
||||
}
|
||||
|
||||
KeyType GetKey() const
|
||||
{
|
||||
return mHost;
|
||||
}
|
||||
|
||||
bool KeyEquals(KeyTypePointer aKey) const
|
||||
{
|
||||
return !strcmp(mHost, aKey);
|
||||
}
|
||||
|
||||
static KeyTypePointer KeyToPointer(KeyType aKey)
|
||||
{
|
||||
return aKey;
|
||||
}
|
||||
|
||||
static PLDHashNumber HashKey(KeyTypePointer aKey)
|
||||
{
|
||||
// PL_DHashStringKey doesn't use the table parameter, so we can safely
|
||||
// pass nullptr
|
||||
return PL_DHashStringKey(nullptr, aKey);
|
||||
}
|
||||
|
||||
// force the hashtable to use the copy constructor when shuffling entries
|
||||
// around, otherwise the Auto part of our nsAutoTArray won't be happy!
|
||||
enum { ALLOW_MEMMOVE = false };
|
||||
|
||||
// Permissions methods
|
||||
inline const nsDependentCString GetHost() const
|
||||
{
|
||||
return nsDependentCString(mHost);
|
||||
}
|
||||
|
||||
inline nsTArray<nsPermissionEntry> & GetPermissions()
|
||||
{
|
||||
return mPermissions;
|
||||
}
|
||||
|
||||
inline int32_t GetPermissionIndex(uint32_t aType) const
|
||||
{
|
||||
for (uint32_t i = 0; i < mPermissions.Length(); ++i)
|
||||
if (mPermissions[i].mType == aType)
|
||||
return i;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
inline nsPermissionEntry GetPermission(uint32_t aType) const
|
||||
{
|
||||
for (uint32_t i = 0; i < mPermissions.Length(); ++i)
|
||||
if (mPermissions[i].mType == aType)
|
||||
return mPermissions[i];
|
||||
|
||||
// unknown permission... return relevant data
|
||||
nsPermissionEntry unk = nsPermissionEntry(aType, nsIPermissionManager::UNKNOWN_ACTION,
|
||||
-1, nsIPermissionManager::EXPIRE_NEVER, 0);
|
||||
return unk;
|
||||
}
|
||||
|
||||
private:
|
||||
const char *mHost;
|
||||
nsAutoTArray<nsPermissionEntry, 1> mPermissions;
|
||||
};
|
||||
|
||||
|
||||
class nsPermissionManager : public nsIPermissionManager,
|
||||
public nsIObserver,
|
||||
public nsSupportsWeakReference
|
||||
{
|
||||
public:
|
||||
class PermissionEntry
|
||||
{
|
||||
public:
|
||||
PermissionEntry(int64_t aID, uint32_t aType, uint32_t aPermission,
|
||||
uint32_t aExpireType, int64_t aExpireTime)
|
||||
: mID(aID)
|
||||
, mType(aType)
|
||||
, mPermission(aPermission)
|
||||
, mExpireType(aExpireType)
|
||||
, mExpireTime(aExpireTime)
|
||||
{}
|
||||
|
||||
int64_t mID;
|
||||
uint32_t mType;
|
||||
uint32_t mPermission;
|
||||
uint32_t mExpireType;
|
||||
int64_t mExpireTime;
|
||||
};
|
||||
|
||||
/**
|
||||
* PermissionKey is the key used by PermissionHashKey hash table.
|
||||
*
|
||||
* NOTE: It could be implementing nsIHashable but there is no reason to worry
|
||||
* with XPCOM interfaces while we don't need to.
|
||||
*/
|
||||
class PermissionKey
|
||||
{
|
||||
public:
|
||||
PermissionKey(nsIPrincipal* aPrincipal);
|
||||
PermissionKey(const nsACString& aHost,
|
||||
uint32_t aAppId,
|
||||
bool aIsInBrowserElement)
|
||||
: mHost(aHost)
|
||||
, mAppId(aAppId)
|
||||
, mIsInBrowserElement(aIsInBrowserElement)
|
||||
{
|
||||
}
|
||||
|
||||
bool operator==(const PermissionKey& aKey) const {
|
||||
return mHost.Equals(aKey.mHost) &&
|
||||
mAppId == aKey.mAppId &&
|
||||
mIsInBrowserElement == aKey.mIsInBrowserElement;
|
||||
}
|
||||
|
||||
PLDHashNumber GetHashCode() const {
|
||||
nsCAutoString str;
|
||||
str.Assign(mHost);
|
||||
str.AppendInt(mAppId);
|
||||
str.AppendInt(static_cast<int32_t>(mIsInBrowserElement));
|
||||
|
||||
return mozilla::HashString(str);
|
||||
}
|
||||
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(PermissionKey);
|
||||
|
||||
nsCString mHost;
|
||||
uint32_t mAppId;
|
||||
bool mIsInBrowserElement;
|
||||
|
||||
private:
|
||||
// Default ctor shouldn't be used.
|
||||
PermissionKey() MOZ_DELETE;
|
||||
|
||||
// Dtor shouldn't be used outside of the class.
|
||||
~PermissionKey() {};
|
||||
};
|
||||
|
||||
class PermissionHashKey : public nsRefPtrHashKey<PermissionKey>
|
||||
{
|
||||
public:
|
||||
PermissionHashKey(const PermissionKey* aPermissionKey)
|
||||
: nsRefPtrHashKey<PermissionKey>(aPermissionKey)
|
||||
{}
|
||||
|
||||
PermissionHashKey(const PermissionHashKey& toCopy)
|
||||
: nsRefPtrHashKey<PermissionKey>(toCopy)
|
||||
, mPermissions(toCopy.mPermissions)
|
||||
{}
|
||||
|
||||
bool KeyEquals(const PermissionKey* aKey) const
|
||||
{
|
||||
return *aKey == *GetKey();
|
||||
}
|
||||
|
||||
static PLDHashNumber HashKey(const PermissionKey* aKey)
|
||||
{
|
||||
return aKey->GetHashCode();
|
||||
}
|
||||
|
||||
// Force the hashtable to use the copy constructor when shuffling entries
|
||||
// around, otherwise the Auto part of our nsAutoTArray won't be happy!
|
||||
enum { ALLOW_MEMMOVE = false };
|
||||
|
||||
inline nsTArray<PermissionEntry> & GetPermissions()
|
||||
{
|
||||
return mPermissions;
|
||||
}
|
||||
|
||||
inline int32_t GetPermissionIndex(uint32_t aType) const
|
||||
{
|
||||
for (uint32_t i = 0; i < mPermissions.Length(); ++i)
|
||||
if (mPermissions[i].mType == aType)
|
||||
return i;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
inline PermissionEntry GetPermission(uint32_t aType) const
|
||||
{
|
||||
for (uint32_t i = 0; i < mPermissions.Length(); ++i)
|
||||
if (mPermissions[i].mType == aType)
|
||||
return mPermissions[i];
|
||||
|
||||
// unknown permission... return relevant data
|
||||
return PermissionEntry(-1, aType, nsIPermissionManager::UNKNOWN_ACTION,
|
||||
nsIPermissionManager::EXPIRE_NEVER, 0);
|
||||
}
|
||||
|
||||
private:
|
||||
nsAutoTArray<PermissionEntry, 1> mPermissions;
|
||||
};
|
||||
|
||||
// nsISupports
|
||||
NS_DECL_ISUPPORTS
|
||||
@ -164,13 +191,14 @@ public:
|
||||
DBOperationType aDBOperation);
|
||||
|
||||
private:
|
||||
|
||||
int32_t GetTypeIndex(const char *aTypeString,
|
||||
bool aAdd);
|
||||
|
||||
nsHostEntry *GetHostEntry(const nsAFlatCString &aHost,
|
||||
uint32_t aType,
|
||||
bool aExactHostMatch);
|
||||
PermissionHashKey* GetPermissionHashKey(const nsACString& aHost,
|
||||
uint32_t aAppId,
|
||||
bool aIsInBrowserElement,
|
||||
uint32_t aType,
|
||||
bool aExactHostMatch);
|
||||
|
||||
nsresult CommonTestPermission(nsIPrincipal* aPrincipal,
|
||||
const char *aType,
|
||||
@ -196,7 +224,6 @@ private:
|
||||
nsresult RemoveAllInternal(bool aNotifyObservers);
|
||||
nsresult RemoveAllFromMemory();
|
||||
nsresult NormalizeToACE(nsCString &aHost);
|
||||
nsresult GetHost(nsIURI *aURI, nsACString &aResult);
|
||||
static void UpdateDB(OperationType aOp,
|
||||
mozIStorageStatement* aStmt,
|
||||
int64_t aID,
|
||||
@ -214,7 +241,7 @@ private:
|
||||
nsCOMPtr<mozIStorageStatement> mStmtDelete;
|
||||
nsCOMPtr<mozIStorageStatement> mStmtUpdate;
|
||||
|
||||
nsTHashtable<nsHostEntry> mHostTable;
|
||||
nsTHashtable<PermissionHashKey> mPermissionTable;
|
||||
// a unique, monotonically increasing id used to identify each database entry
|
||||
int64_t mLargestID;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user