Back out bug 777072, bug 619236, and bug 784878

This commit is contained in:
Chris Jones 2012-08-23 22:00:14 -07:00
parent 58293031d8
commit da27f385d7
15 changed files with 316 additions and 713 deletions

View File

@ -264,9 +264,6 @@ class Automation(object):
# Open database and create table
permDB = sqlite3.connect(os.path.join(profileDir, "permissions.sqlite"))
cursor = permDB.cursor();
cursor.execute("PRAGMA user_version=3");
# SQL copied from nsPermissionManager.cpp
cursor.execute("""CREATE TABLE moz_hosts (
id INTEGER PRIMARY KEY,
@ -274,16 +271,14 @@ class Automation(object):
type TEXT,
permission INTEGER,
expireType INTEGER,
expireTime INTEGER,
appId INTEGER,
isInBrowserElement INTEGER)""")
expireTime INTEGER)""")
# Insert desired permissions
c = 0
for perm in permissions.keys():
for host,allow in permissions[perm]:
c += 1
cursor.execute("INSERT INTO moz_hosts values(?, ?, ?, ?, 0, 0, 0, 0)",
cursor.execute("INSERT INTO moz_hosts values(?, ?, ?, ?, 0, 0)",
(c, host, perm, 1 if allow else 2))
# Commit and close

View File

@ -389,8 +389,6 @@ function runTest() {
checkIFrame(this, data);
};
iframe.addChild = function() {
SpecialPowers.addPermission("browser", true, iframe.contentDocument);
var childFrame = document.createElement('iframe');
if (data.child.app) {
@ -431,6 +429,7 @@ function runTest() {
var gTestRunner = runTest();
SpecialPowers.addPermission("browser", true, "http://example.org");
SpecialPowers.pushPrefEnv({'set':[["dom.mozBrowserFramesEnabled", true]]},
function() { gTestRunner.next(); });

View File

@ -18,11 +18,6 @@ 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;
@ -60,12 +55,6 @@ 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();
}

View File

@ -12,11 +12,6 @@ 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;
@ -40,7 +35,7 @@ function runTest() {
SimpleTest.executeSoon(function() {
SimpleTest.executeSoon(function() {
SimpleTest.executeSoon(function() {
finish();
SimpleTest.finish();
});
});
});
@ -55,13 +50,4 @@ 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();

View File

@ -94,9 +94,6 @@
#include "nsDOMFile.h"
#include "nsIRemoteBlob.h"
#include "StructuredCloneUtils.h"
#include "nsIScriptSecurityManager.h"
#include "nsContentUtils.h"
#include "nsIPrincipal.h"
using namespace mozilla::docshell;
using namespace mozilla::dom::devicestorage;
@ -844,20 +841,7 @@ ContentChild::RecvAddPermission(const IPC::Permission& permission)
NS_ABORT_IF_FALSE(permissionManager,
"We have no permissionManager in the Content process !");
nsCOMPtr<nsIURI> uri;
NS_NewURI(getter_AddRefs(uri), NS_LITERAL_CSTRING("http://") + nsCString(permission.host));
NS_ENSURE_TRUE(uri, true);
nsIScriptSecurityManager* secMan = nsContentUtils::GetSecurityManager();
MOZ_ASSERT(secMan);
nsCOMPtr<nsIPrincipal> principal;
nsresult rv = secMan->GetAppCodebasePrincipal(uri, permission.appId,
permission.isInBrowserElement,
getter_AddRefs(principal));
NS_ENSURE_SUCCESS(rv, true);
permissionManager->AddInternal(principal,
permissionManager->AddInternal(nsCString(permission.host),
nsCString(permission.type),
permission.capability,
0,

View File

@ -773,10 +773,6 @@ ContentParent::RecvReadPermissions(InfallibleTArray<IPC::Permission>* aPermissio
nsCString host;
perm->GetHost(host);
uint32_t appId;
perm->GetAppId(&appId);
bool isInBrowserElement;
perm->GetIsInBrowserElement(&isInBrowserElement);
nsCString type;
perm->GetType(type);
uint32_t capability;
@ -786,10 +782,8 @@ ContentParent::RecvReadPermissions(InfallibleTArray<IPC::Permission>* aPermissio
int64_t expireTime;
perm->GetExpireTime(&expireTime);
aPermissions->AppendElement(IPC::Permission(host, appId,
isInBrowserElement, type,
capability, expireType,
expireTime));
aPermissions->AppendElement(IPC::Permission(host, type, capability,
expireType, expireTime));
}
// Ask for future changes

View File

@ -10,8 +10,6 @@
NS_IMPL_ISUPPORTS1(nsPermission, nsIPermission)
nsPermission::nsPermission(const nsACString &aHost,
uint32_t aAppId,
bool aIsInBrowserElement,
const nsACString &aType,
uint32_t aCapability,
uint32_t aExpireType,
@ -21,8 +19,10 @@ nsPermission::nsPermission(const nsACString &aHost,
, mCapability(aCapability)
, mExpireType(aExpireType)
, mExpireTime(aExpireTime)
, mAppId(aAppId)
, mIsInBrowserElement(aIsInBrowserElement)
{
}
nsPermission::~nsPermission()
{
}
@ -33,20 +33,6 @@ nsPermission::GetHost(nsACString &aHost)
return NS_OK;
}
NS_IMETHODIMP
nsPermission::GetAppId(uint32_t* aAppId)
{
*aAppId = mAppId;
return NS_OK;
}
NS_IMETHODIMP
nsPermission::GetIsInBrowserElement(bool* aIsInBrowserElement)
{
*aIsInBrowserElement = mIsInBrowserElement;
return NS_OK;
}
NS_IMETHODIMP
nsPermission::GetType(nsACString &aType)
{

View File

@ -19,23 +19,19 @@ public:
NS_DECL_NSIPERMISSION
nsPermission(const nsACString &aHost,
uint32_t aAppId,
bool aIsInBrowserElement,
const nsACString &aType,
const nsACString &aType,
uint32_t aCapability,
uint32_t aExpireType,
int64_t aExpireTime);
virtual ~nsPermission() {};
virtual ~nsPermission();
protected:
nsCString mHost;
nsCString mType;
uint32_t mCapability;
uint32_t mExpireType;
int64_t mExpireTime;
uint32_t mAppId;
bool mIsInBrowserElement;
};
#endif // nsPermission_h__

View File

@ -23,7 +23,6 @@
#include "nsXULAppAPI.h"
#include "nsIPrincipal.h"
#include "nsContentUtils.h"
#include "nsIScriptSecurityManager.h"
static nsPermissionManager *gPermissionManager = nullptr;
@ -71,66 +70,42 @@ ChildProcess()
////////////////////////////////////////////////////////////////////////////////
namespace {
#define PL_ARENA_CONST_ALIGN_MASK 3
#include "plarena.h"
nsresult
GetPrincipal(const nsACString& aHost, uint32_t aAppId, bool aIsInBrowserElement,
nsIPrincipal** aPrincipal)
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)
{
nsIScriptSecurityManager* secMan = nsContentUtils::GetSecurityManager();
NS_ENSURE_TRUE(secMan, NS_ERROR_FAILURE);
nsCOMPtr<nsIURI> uri;
// NOTE: we use "http://" as a protocal but we will just use the host so it
// doesn't really matter.
NS_NewURI(getter_AddRefs(uri), NS_LITERAL_CSTRING("http://") + aHost);
return secMan->GetAppCodebasePrincipal(uri, aAppId, aIsInBrowserElement, aPrincipal);
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);
}
nsresult
GetPrincipal(nsIURI* aURI, nsIPrincipal** aPrincipal)
nsHostEntry::nsHostEntry(const char* aHost)
{
nsIScriptSecurityManager* secMan = nsContentUtils::GetSecurityManager();
NS_ENSURE_TRUE(secMan, NS_ERROR_FAILURE);
return secMan->GetNoAppCodebasePrincipal(aURI, aPrincipal);
mHost = ArenaStrDup(aHost, gHostArena);
}
nsresult
GetPrincipal(const nsACString& aHost, nsIPrincipal** aPrincipal)
// XXX this can fail on OOM
nsHostEntry::nsHostEntry(const nsHostEntry& toCopy)
: mHost(toCopy.mHost)
, mPermissions(toCopy.mPermissions)
{
return GetPrincipal(aHost, nsIScriptSecurityManager::NO_APP_ID, false, 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
////////////////////////////////////////////////////////////////////////////////
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
@ -242,7 +217,7 @@ NS_IMETHODIMP DeleteFromMozHostListener::HandleCompletion(uint16_t aReason)
// nsPermissionManager Implementation
static const char kPermissionsFileName[] = "permissions.sqlite";
#define HOSTS_SCHEMA_VERSION 3
#define HOSTS_SCHEMA_VERSION 2
static const char kHostpermFileName[] = "hostperm.1";
@ -293,7 +268,7 @@ nsPermissionManager::Init()
{
nsresult rv;
mPermissionTable.Init();
mHostTable.Init();
mObserverService = do_GetService("@mozilla.org/observer-service;1", &rv);
if (NS_SUCCEEDED(rv)) {
@ -308,12 +283,7 @@ nsPermissionManager::Init()
for (uint32_t i = 0; i < perms.Length(); i++) {
const IPC::Permission &perm = perms[i];
nsCOMPtr<nsIPrincipal> principal;
rv = GetPrincipal(perm.host, perm.appId, perm.isInBrowserElement, getter_AddRefs(principal));
NS_ENSURE_SUCCESS(rv, rv);
AddInternal(principal, perm.type, perm.capability, 0, perm.expireType,
AddInternal(perm.host, perm.type, perm.capability, 0, perm.expireType,
perm.expireTime, eNotify, eNoDBOperation);
}
@ -404,33 +374,31 @@ nsPermissionManager::InitDB(bool aRemoveFile)
rv = mDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
"ALTER TABLE moz_hosts ADD expireTime INTEGER"));
NS_ENSURE_SUCCESS(rv, rv);
}
// fall through to the next upgrade
// TODO: we want to make default version as version 2 in order to fix bug 784875.
case 0:
case 2:
{
// Add appId/isInBrowserElement fields.
rv = mDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
"ALTER TABLE moz_hosts ADD appId INTEGER"));
NS_ENSURE_SUCCESS(rv, rv);
rv = mDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
"ALTER TABLE moz_hosts ADD isInBrowserElement INTEGER"));
NS_ENSURE_SUCCESS(rv, rv);
rv = mDBConn->SetSchemaVersion(HOSTS_SCHEMA_VERSION);
NS_ENSURE_SUCCESS(rv, rv);
}
// fall through to the next upgrade
// current version.
case HOSTS_SCHEMA_VERSION:
break;
case 0:
{
NS_WARNING("couldn't get schema version!");
// the table may be usable; someone might've just clobbered the schema
// version. we can treat this case like a downgrade using the codepath
// below, by verifying the columns we care about are all there. for now,
// re-set the schema version in the db, in case the checks succeed (if
// they don't, we're dropping the table anyway).
rv = mDBConn->SetSchemaVersion(HOSTS_SCHEMA_VERSION);
NS_ENSURE_SUCCESS(rv, rv);
}
// fall through to downgrade check
// downgrading.
// if columns have been added to the table, we can still use the ones we
// understand safely. if columns have been deleted or altered, just
@ -442,7 +410,7 @@ nsPermissionManager::InitDB(bool aRemoveFile)
// check if all the expected columns exist
nsCOMPtr<mozIStorageStatement> stmt;
rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING(
"SELECT host, type, permission, expireType, expireTime, appId, isInBrowserElement FROM moz_hosts"),
"SELECT host, type, permission, expireType, expireTime FROM moz_hosts"),
getter_AddRefs(stmt));
if (NS_SUCCEEDED(rv))
break;
@ -464,8 +432,8 @@ nsPermissionManager::InitDB(bool aRemoveFile)
// cache frequently used statements (for insertion, deletion, and updating)
rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING(
"INSERT INTO moz_hosts "
"(id, host, type, permission, expireType, expireTime, appId, isInBrowserElement) "
"VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8)"), getter_AddRefs(mStmtInsert));
"(id, host, type, permission, expireType, expireTime) "
"VALUES (?1, ?2, ?3, ?4, ?5, ?6)"), getter_AddRefs(mStmtInsert));
NS_ENSURE_SUCCESS(rv, rv);
rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING(
@ -505,8 +473,6 @@ nsPermissionManager::CreateTable()
",permission INTEGER"
",expireType INTEGER"
",expireTime INTEGER"
",appId INTEGER"
",isInBrowserElement INTEGER"
")"));
}
@ -517,13 +483,28 @@ nsPermissionManager::Add(nsIURI *aURI,
uint32_t aExpireType,
int64_t aExpireTime)
{
NS_ENSURE_ARG_POINTER(aURI);
ENSURE_NOT_CHILD_PROCESS;
nsCOMPtr<nsIPrincipal> principal;
nsresult rv = GetPrincipal(aURI, getter_AddRefs(principal));
NS_ENSURE_ARG_POINTER(aURI);
NS_ENSURE_ARG_POINTER(aType);
NS_ENSURE_TRUE(aExpireType == nsIPermissionManager::EXPIRE_NEVER ||
aExpireType == nsIPermissionManager::EXPIRE_TIME ||
aExpireType == nsIPermissionManager::EXPIRE_SESSION,
NS_ERROR_INVALID_ARG);
nsresult rv;
// Skip addition if the permission is already expired.
if (aExpireType == nsIPermissionManager::EXPIRE_TIME &&
aExpireTime <= PR_Now() / 1000)
return NS_OK;
nsCAutoString host;
rv = GetHost(aURI, host);
NS_ENSURE_SUCCESS(rv, rv);
return AddFromPrincipal(principal, aType, aPermission, aExpireType, aExpireTime);
return AddInternal(host, nsDependentCString(aType), aPermission, 0,
aExpireType, aExpireTime, eNotify, eWriteToDB);
}
NS_IMETHODIMP
@ -531,19 +512,7 @@ nsPermissionManager::AddFromPrincipal(nsIPrincipal* aPrincipal,
const char* aType, uint32_t aPermission,
uint32_t aExpireType, int64_t aExpireTime)
{
ENSURE_NOT_CHILD_PROCESS;
NS_ENSURE_ARG_POINTER(aPrincipal);
NS_ENSURE_ARG_POINTER(aType);
NS_ENSURE_TRUE(aExpireType == nsIPermissionManager::EXPIRE_NEVER ||
aExpireType == nsIPermissionManager::EXPIRE_TIME ||
aExpireType == nsIPermissionManager::EXPIRE_SESSION,
NS_ERROR_INVALID_ARG);
// Skip addition if the permission is already expired.
if (aExpireType == nsIPermissionManager::EXPIRE_TIME &&
aExpireTime <= (PR_Now() / 1000)) {
return NS_OK;
}
// We don't add the system principal because it actually has no URI and we
// always allow action for them.
@ -551,12 +520,14 @@ nsPermissionManager::AddFromPrincipal(nsIPrincipal* aPrincipal,
return NS_OK;
}
return AddInternal(aPrincipal, nsDependentCString(aType), aPermission, 0,
aExpireType, aExpireTime, eNotify, eWriteToDB);
nsCOMPtr<nsIURI> uri;
aPrincipal->GetURI(getter_AddRefs(uri));
return Add(uri, aType, aPermission, aExpireType, aExpireTime);
}
nsresult
nsPermissionManager::AddInternal(nsIPrincipal* aPrincipal,
nsPermissionManager::AddInternal(const nsAFlatCString &aHost,
const nsAFlatCString &aType,
uint32_t aPermission,
int64_t aID,
@ -565,20 +536,9 @@ nsPermissionManager::AddInternal(nsIPrincipal* aPrincipal,
NotifyOperationType aNotifyOperation,
DBOperationType aDBOperation)
{
nsCAutoString host;
nsresult rv = GetHostForPrincipal(aPrincipal, host);
NS_ENSURE_SUCCESS(rv, rv);
if (!IsChildProcess()) {
uint32_t appId;
rv = aPrincipal->GetAppId(&appId);
NS_ENSURE_SUCCESS(rv, rv);
bool isInBrowserElement;
rv = aPrincipal->GetIsInBrowserElement(&isInBrowserElement);
NS_ENSURE_SUCCESS(rv, rv);
IPC::Permission permission(host, appId, isInBrowserElement, aType,
IPC::Permission permission((aHost),
(aType),
aPermission, aExpireType, aExpireTime);
nsTArray<ContentParent*> cplist;
@ -590,17 +550,23 @@ 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
nsRefPtr<PermissionKey> key = new PermissionKey(aPrincipal);
PermissionHashKey* entry = mPermissionTable.PutEntry(key);
nsHostEntry *entry = mHostTable.PutEntry(aHost.get());
if (!entry) return NS_ERROR_FAILURE;
if (!entry->GetKey()) {
mPermissionTable.RawRemoveEntry(entry);
mHostTable.RawRemoveEntry(entry);
return NS_ERROR_OUT_OF_MEMORY;
}
@ -614,7 +580,7 @@ nsPermissionManager::AddInternal(nsIPrincipal* aPrincipal,
op = eOperationAdding;
} else {
PermissionEntry oldPermissionEntry = entry->GetPermissions()[index];
nsPermissionEntry 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
@ -652,24 +618,13 @@ nsPermissionManager::AddInternal(nsIPrincipal* aPrincipal,
id = aID;
}
entry->GetPermissions().AppendElement(PermissionEntry(id, typeIndex, aPermission, aExpireType, aExpireTime));
entry->GetPermissions().AppendElement(nsPermissionEntry(typeIndex, aPermission, id, aExpireType, aExpireTime));
if (aDBOperation == eWriteToDB && aExpireType != nsIPermissionManager::EXPIRE_SESSION) {
uint32_t appId;
rv = aPrincipal->GetAppId(&appId);
NS_ENSURE_SUCCESS(rv, rv);
bool isInBrowserElement;
rv = aPrincipal->GetIsInBrowserElement(&isInBrowserElement);
NS_ENSURE_SUCCESS(rv, rv);
UpdateDB(op, mStmtInsert, id, host, aType, aPermission, aExpireType, aExpireTime, appId, isInBrowserElement);
}
if (aDBOperation == eWriteToDB && aExpireType != nsIPermissionManager::EXPIRE_SESSION)
UpdateDB(op, mStmtInsert, id, aHost, aType, aPermission, aExpireType, aExpireTime);
if (aNotifyOperation == eNotify) {
NotifyObserversWithPermission(host,
entry->GetKey()->mAppId,
entry->GetKey()->mIsInBrowserElement,
NotifyObserversWithPermission(aHost,
mTypeArray[typeIndex],
aPermission,
aExpireType,
@ -682,24 +637,20 @@ nsPermissionManager::AddInternal(nsIPrincipal* aPrincipal,
case eOperationRemoving:
{
PermissionEntry oldPermissionEntry = entry->GetPermissions()[index];
nsPermissionEntry oldPermissionEntry = entry->GetPermissions()[index];
id = oldPermissionEntry.mID;
entry->GetPermissions().RemoveElementAt(index);
// If no more types are present, remove the entry
if (entry->GetPermissions().IsEmpty())
mPermissionTable.RawRemoveEntry(entry);
mHostTable.RawRemoveEntry(entry);
if (aDBOperation == eWriteToDB)
// We care only about the id here so we pass dummy values for all other
// parameters.
UpdateDB(op, mStmtDelete, id, EmptyCString(), EmptyCString(), 0,
nsIPermissionManager::EXPIRE_NEVER, 0, 0, false);
UpdateDB(op, mStmtDelete, id, EmptyCString(), EmptyCString(), 0,
nsIPermissionManager::EXPIRE_NEVER, 0);
if (aNotifyOperation == eNotify) {
NotifyObserversWithPermission(host,
entry->GetKey()->mAppId,
entry->GetKey()->mIsInBrowserElement,
NotifyObserversWithPermission(aHost,
mTypeArray[typeIndex],
oldPermissionEntry.mPermission,
oldPermissionEntry.mExpireType,
@ -716,15 +667,10 @@ nsPermissionManager::AddInternal(nsIPrincipal* aPrincipal,
entry->GetPermissions()[index].mPermission = aPermission;
if (aDBOperation == eWriteToDB && aExpireType != nsIPermissionManager::EXPIRE_SESSION)
// We care only about the id, the permission and expireType/expireTime here.
// We pass dummy values for all other parameters.
UpdateDB(op, mStmtUpdate, id, EmptyCString(), EmptyCString(),
aPermission, aExpireType, aExpireTime, 0, false);
UpdateDB(op, mStmtUpdate, id, EmptyCString(), EmptyCString(), aPermission, aExpireType, aExpireTime);
if (aNotifyOperation == eNotify) {
NotifyObserversWithPermission(host,
entry->GetKey()->mAppId,
entry->GetKey()->mIsInBrowserElement,
NotifyObserversWithPermission(aHost,
mTypeArray[typeIndex],
aPermission,
aExpireType,
@ -742,29 +688,13 @@ nsPermissionManager::AddInternal(nsIPrincipal* aPrincipal,
NS_IMETHODIMP
nsPermissionManager::Remove(const nsACString &aHost,
const char *aType)
{
nsCOMPtr<nsIPrincipal> principal;
nsresult rv = GetPrincipal(aHost, getter_AddRefs(principal));
NS_ENSURE_SUCCESS(rv, rv);
return RemoveFromPrincipal(principal, aType);
}
NS_IMETHODIMP
nsPermissionManager::RemoveFromPrincipal(nsIPrincipal* aPrincipal,
const char* aType)
{
ENSURE_NOT_CHILD_PROCESS;
NS_ENSURE_ARG_POINTER(aPrincipal);
NS_ENSURE_ARG_POINTER(aType);
// System principals are never added to the database, no need to remove them.
if (nsContentUtils::IsSystemPrincipal(aPrincipal)) {
return NS_OK;
}
// AddInternal() handles removal, just let it do the work
return AddInternal(aPrincipal,
return AddInternal(PromiseFlatCString(aHost),
nsDependentCString(aType),
nsIPermissionManager::UNKNOWN_ACTION,
0,
@ -774,6 +704,27 @@ nsPermissionManager::RemoveFromPrincipal(nsIPrincipal* aPrincipal,
eWriteToDB);
}
NS_IMETHODIMP
nsPermissionManager::RemoveFromPrincipal(nsIPrincipal* aPrincipal,
const char* aType)
{
NS_ENSURE_ARG_POINTER(aPrincipal);
// System principals are never added to the database, no need to remove them.
if (nsContentUtils::IsSystemPrincipal(aPrincipal)) {
return NS_OK;
}
nsCOMPtr<nsIURI> uri;
aPrincipal->GetURI(getter_AddRefs(uri));
NS_ENSURE_TRUE(uri, NS_ERROR_FAILURE);
nsCAutoString host;
uri->GetHost(host);
return Remove(host, aType);
}
NS_IMETHODIMP
nsPermissionManager::RemoveAll()
{
@ -835,28 +786,7 @@ nsPermissionManager::TestExactPermission(nsIURI *aURI,
const char *aType,
uint32_t *aPermission)
{
nsCOMPtr<nsIPrincipal> principal;
nsresult rv = GetPrincipal(aURI, getter_AddRefs(principal));
NS_ENSURE_SUCCESS(rv, rv);
return TestExactPermissionFromPrincipal(principal, aType, aPermission);
}
NS_IMETHODIMP
nsPermissionManager::TestExactPermissionFromPrincipal(nsIPrincipal* aPrincipal,
const char* aType,
uint32_t* aPermission)
{
NS_ENSURE_ARG_POINTER(aPrincipal);
// System principals do not have URI so we can't try to get
// retro-compatibility here.
if (nsContentUtils::IsSystemPrincipal(aPrincipal)) {
*aPermission = nsIPermissionManager::ALLOW_ACTION;
return NS_OK;
}
return CommonTestPermission(aPrincipal, aType, aPermission, true);
return CommonTestPermission(aURI, aType, aPermission, true);
}
NS_IMETHODIMP
@ -864,11 +794,7 @@ nsPermissionManager::TestPermission(nsIURI *aURI,
const char *aType,
uint32_t *aPermission)
{
nsCOMPtr<nsIPrincipal> principal;
nsresult rv = GetPrincipal(aURI, getter_AddRefs(principal));
NS_ENSURE_SUCCESS(rv, rv);
return TestPermissionFromPrincipal(principal, aType, aPermission);
return CommonTestPermission(aURI, aType, aPermission, false);
}
NS_IMETHODIMP
@ -885,33 +811,51 @@ nsPermissionManager::TestPermissionFromPrincipal(nsIPrincipal* aPrincipal,
return NS_OK;
}
return CommonTestPermission(aPrincipal, aType, aPermission, false);
nsCOMPtr<nsIURI> uri;
aPrincipal->GetURI(getter_AddRefs(uri));
return TestPermission(uri, aType, aPermission);
}
NS_IMETHODIMP
nsPermissionManager::TestExactPermissionFromPrincipal(nsIPrincipal* aPrincipal,
const char* aType,
uint32_t* aPermission)
{
NS_ENSURE_ARG_POINTER(aPrincipal);
// System principals do not have URI so we can't try to get
// retro-compatibility here.
if (nsContentUtils::IsSystemPrincipal(aPrincipal)) {
*aPermission = nsIPermissionManager::ALLOW_ACTION;
return NS_OK;
}
nsCOMPtr<nsIURI> uri;
aPrincipal->GetURI(getter_AddRefs(uri));
return TestExactPermission(uri, aType, aPermission);
}
nsresult
nsPermissionManager::CommonTestPermission(nsIPrincipal* aPrincipal,
nsPermissionManager::CommonTestPermission(nsIURI *aURI,
const char *aType,
uint32_t *aPermission,
bool aExactHostMatch)
{
NS_ENSURE_ARG_POINTER(aPrincipal);
NS_ENSURE_ARG_POINTER(aURI);
NS_ENSURE_ARG_POINTER(aType);
// set the default
*aPermission = nsIPermissionManager::UNKNOWN_ACTION;
nsCOMPtr<nsIURI> uri;
nsresult rv = aPrincipal->GetURI(getter_AddRefs(uri));
NS_ENSURE_SUCCESS(rv, rv);
nsCAutoString host;
rv = GetHostForPrincipal(aPrincipal, host);
nsresult rv = GetHost(aURI, 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.
if (NS_FAILED(rv)) {
bool isFile;
rv = uri->SchemeIs("file", &isFile);
rv = aURI->SchemeIs("file", &isFile);
NS_ENSURE_SUCCESS(rv, rv);
if (isFile) {
host.AssignLiteral("<file>");
@ -920,64 +864,44 @@ nsPermissionManager::CommonTestPermission(nsIPrincipal* aPrincipal,
return NS_OK;
}
}
int32_t typeIndex = GetTypeIndex(aType, false);
// If type == -1, the type isn't known,
// so just return NS_OK
if (typeIndex == -1) return NS_OK;
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) {
nsHostEntry *entry = GetHostEntry(host, typeIndex, aExactHostMatch);
if (entry)
*aPermission = entry->GetPermission(typeIndex).mPermission;
}
return NS_OK;
}
// 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.
// Get hostentry for given host string and permission type.
// walk up the domain if needed.
// return 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.
nsPermissionManager::PermissionHashKey*
nsPermissionManager::GetPermissionHashKey(const nsACString& aHost,
uint32_t aAppId,
bool aIsInBrowserElement,
uint32_t aType,
bool aExactHostMatch)
nsHostEntry *
nsPermissionManager::GetHostEntry(const nsAFlatCString &aHost,
uint32_t aType,
bool aExactHostMatch)
{
uint32_t offset = 0;
PermissionHashKey* entry;
nsHostEntry *entry;
int64_t now = PR_Now() / 1000;
do {
nsRefPtr<PermissionKey> key = new PermissionKey(Substring(aHost, offset), aAppId, aIsInBrowserElement);
entry = mPermissionTable.GetEntry(key);
entry = mHostTable.GetEntry(aHost.get() + offset);
if (entry) {
PermissionEntry permEntry = entry->GetPermission(aType);
nsPermissionEntry permEntry = entry->GetPermission(aType);
// if the entry is expired, remove and keep looking for others.
if (permEntry.mExpireType == nsIPermissionManager::EXPIRE_TIME &&
permEntry.mExpireTime <= now) {
nsCOMPtr<nsIPrincipal> principal;
if (NS_FAILED(GetPrincipal(aHost, aAppId, aIsInBrowserElement, getter_AddRefs(principal)))) {
return nullptr;
}
RemoveFromPrincipal(principal, mTypeArray[aType].get());
} else if (permEntry.mPermission != nsIPermissionManager::UNKNOWN_ACTION) {
permEntry.mExpireTime <= now)
Remove(aHost, mTypeArray[aType].get());
else if (permEntry.mPermission != nsIPermissionManager::UNKNOWN_ACTION)
break;
}
// reset entry, to be able to return null on failure
entry = nullptr;
@ -1005,16 +929,14 @@ struct nsGetEnumeratorData
};
static PLDHashOperator
AddPermissionsToList(nsPermissionManager::PermissionHashKey* entry, void *arg)
AddPermissionsToList(nsHostEntry *entry, void *arg)
{
nsGetEnumeratorData *data = static_cast<nsGetEnumeratorData *>(arg);
for (uint32_t i = 0; i < entry->GetPermissions().Length(); ++i) {
nsPermissionManager::PermissionEntry& permEntry = entry->GetPermissions()[i];
nsPermissionEntry &permEntry = entry->GetPermissions()[i];
nsPermission *perm = new nsPermission(entry->GetKey()->mHost,
entry->GetKey()->mAppId,
entry->GetKey()->mIsInBrowserElement,
nsPermission *perm = new nsPermission(entry->GetHost(),
data->types->ElementAt(permEntry.mType),
permEntry.mPermission,
permEntry.mExpireType,
@ -1032,7 +954,7 @@ NS_IMETHODIMP nsPermissionManager::GetEnumerator(nsISimpleEnumerator **aEnum)
nsCOMArray<nsIPermission> array;
nsGetEnumeratorData data(&array, &mTypeArray);
mPermissionTable.EnumerateEntries(AddPermissionsToList, &data);
mHostTable.EnumerateEntries(AddPermissionsToList, &data);
return NS_NewArrayEnumerator(aEnum, array);
}
@ -1070,8 +992,12 @@ nsPermissionManager::RemoveAllFromMemory()
{
mLargestID = 0;
mTypeArray.Clear();
mPermissionTable.Clear();
mHostTable.Clear();
if (gHostArena) {
PL_FinishArenaPool(gHostArena);
delete gHostArena;
}
gHostArena = nullptr;
return NS_OK;
}
@ -1103,8 +1029,6 @@ nsPermissionManager::GetTypeIndex(const char *aType,
// set into an nsIPermission.
void
nsPermissionManager::NotifyObserversWithPermission(const nsACString &aHost,
uint32_t aAppId,
bool aIsInBrowserElement,
const nsCString &aType,
uint32_t aPermission,
uint32_t aExpireType,
@ -1112,8 +1036,7 @@ nsPermissionManager::NotifyObserversWithPermission(const nsACString &aHost,
const PRUnichar *aData)
{
nsCOMPtr<nsIPermission> permission =
new nsPermission(aHost, aAppId, aIsInBrowserElement, aType, aPermission,
aExpireType, aExpireTime);
new nsPermission(aHost, aType, aPermission, aExpireType, aExpireTime);
if (permission)
NotifyObservers(permission, aData);
}
@ -1163,7 +1086,7 @@ nsPermissionManager::Read()
nsCOMPtr<mozIStorageStatement> stmt;
rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING(
"SELECT id, host, type, permission, expireType, expireTime, appId, isInBrowserElement "
"SELECT id, host, type, permission, expireType, expireTime "
"FROM moz_hosts"), getter_AddRefs(stmt));
NS_ENSURE_SUCCESS(rv, rv);
@ -1172,8 +1095,6 @@ nsPermissionManager::Read()
uint32_t permission;
uint32_t expireType;
int64_t expireTime;
uint32_t appId;
bool isInBrowserElement;
bool hasResult;
while (NS_SUCCEEDED(stmt->ExecuteStep(&hasResult)) && hasResult) {
// explicitly set our entry id counter for use in AddInternal(),
@ -1194,15 +1115,7 @@ nsPermissionManager::Read()
// convert into int64_t value (milliseconds)
expireTime = stmt->AsInt64(5);
MOZ_ASSERT(stmt->AsInt64(6) >= 0);
appId = static_cast<uint32_t>(stmt->AsInt64(6));
isInBrowserElement = static_cast<bool>(stmt->AsInt32(7));
nsCOMPtr<nsIPrincipal> principal;
nsresult rv = GetPrincipal(host, appId, isInBrowserElement, getter_AddRefs(principal));
NS_ENSURE_SUCCESS(rv, rv);
rv = AddInternal(principal, type, permission, id, expireType, expireTime,
rv = AddInternal(host, type, permission, id, expireType, expireTime,
eDontNotify, eNoDBOperation);
NS_ENSURE_SUCCESS(rv, rv);
}
@ -1272,11 +1185,7 @@ nsPermissionManager::Import()
continue;
}
nsCOMPtr<nsIPrincipal> principal;
nsresult rv = GetPrincipal(lineArray[3], getter_AddRefs(principal));
NS_ENSURE_SUCCESS(rv, rv);
rv = AddInternal(principal, lineArray[1], permission, 0,
rv = AddInternal(lineArray[3], lineArray[1], permission, 0,
nsIPermissionManager::EXPIRE_NEVER, 0, eDontNotify, eWriteToDB);
NS_ENSURE_SUCCESS(rv, rv);
}
@ -1301,6 +1210,20 @@ 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,
@ -1309,9 +1232,7 @@ nsPermissionManager::UpdateDB(OperationType aOp,
const nsACString &aType,
uint32_t aPermission,
uint32_t aExpireType,
int64_t aExpireTime,
uint32_t aAppId,
bool aIsInBrowserElement)
int64_t aExpireTime)
{
ENSURE_NOT_CHILD_PROCESS_NORET;
@ -1340,12 +1261,6 @@ nsPermissionManager::UpdateDB(OperationType aOp,
if (NS_FAILED(rv)) break;
rv = aStmt->BindInt64ByIndex(5, aExpireTime);
if (NS_FAILED(rv)) break;
rv = aStmt->BindInt64ByIndex(6, aAppId);
if (NS_FAILED(rv)) break;
rv = aStmt->BindInt64ByIndex(7, aIsInBrowserElement);
break;
}

View File

@ -16,8 +16,6 @@
#include "nsTArray.h"
#include "nsString.h"
#include "nsPermission.h"
#include "nsHashKeys.h"
#include "nsAutoPtr.h"
class nsIPermission;
class nsIIDNService;
@ -26,132 +24,107 @@ 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
@ -181,7 +154,7 @@ public:
eNotify
};
nsresult AddInternal(nsIPrincipal* aPrincipal,
nsresult AddInternal(const nsAFlatCString &aHost,
const nsAFlatCString &aType,
uint32_t aPermission,
int64_t aID,
@ -191,16 +164,15 @@ public:
DBOperationType aDBOperation);
private:
int32_t GetTypeIndex(const char *aTypeString,
bool aAdd);
PermissionHashKey* GetPermissionHashKey(const nsACString& aHost,
uint32_t aAppId,
bool aIsInBrowserElement,
uint32_t aType,
bool aExactHostMatch);
nsHostEntry *GetHostEntry(const nsAFlatCString &aHost,
uint32_t aType,
bool aExactHostMatch);
nsresult CommonTestPermission(nsIPrincipal* aPrincipal,
nsresult CommonTestPermission(nsIURI *aURI,
const char *aType,
uint32_t *aPermission,
bool aExactHostMatch);
@ -210,8 +182,6 @@ private:
nsresult Import();
nsresult Read();
void NotifyObserversWithPermission(const nsACString &aHost,
uint32_t aAppId,
bool aIsInBrowserElement,
const nsCString &aType,
uint32_t aPermission,
uint32_t aExpireType,
@ -226,6 +196,7 @@ 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,
@ -233,9 +204,7 @@ private:
const nsACString &aType,
uint32_t aPermission,
uint32_t aExpireType,
int64_t aExpireTime,
uint32_t aAppId,
bool aIsInBrowserElement);
int64_t aExpireTime);
nsCOMPtr<nsIObserverService> mObserverService;
nsCOMPtr<nsIIDNService> mIDNService;
@ -245,7 +214,7 @@ private:
nsCOMPtr<mozIStorageStatement> mStmtDelete;
nsCOMPtr<mozIStorageStatement> mStmtUpdate;
nsTHashtable<PermissionHashKey> mPermissionTable;
nsTHashtable<nsHostEntry> mHostTable;
// a unique, monotonically increasing id used to identify each database entry
int64_t mLargestID;

View File

@ -52,10 +52,6 @@ MOCHITEST_FILES = \
file_loopback_inner.html \
$(NULL)
MOCHITEST_CHROME_FILES = \
test_permissionmanager_app_isolation.html \
$(NULL)
MOCHITEST_BROWSER_FILES = \
browser_test_favicon.js \
$(NULL)

View File

@ -1,168 +0,0 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=758258
-->
<head>
<meta charset="utf-8">
<title>Test for nsIPrincipal extendedOrigin, appStatus and appId</title>
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=758258">Mozilla Bug 758258</a>
<p id="display"></p>
<div id="content">
</div>
<pre id="test">
<script type="application/javascript;version=1.7">
/** Test for Bug 758258 **/
var Ci = Components.interfaces;
var Cc = Components.classes;
SimpleTest.waitForExplicitFinish();
var permManager = Cc["@mozilla.org/permissionmanager;1"]
.getService(Ci.nsIPermissionManager);
const gPermName = 'foobar';
var previousPrefs = {
mozBrowserFramesEnabled: undefined,
};
try {
previousPrefs.mozBrowserFramesEnabled = SpecialPowers.getBoolPref('dom.mozBrowserFramesEnabled');
} catch(e)
{
}
SpecialPowers.setBoolPref('dom.mozBrowserFramesEnabled', true);
// We use http://test/ as url so all apps use the same url and app isolation is
// more obvious.
var gData = [
// APP 1
{
app: 'http://example.org/manifest.webapp',
action: 'read-no',
src: 'http://test/',
},
{
app: 'http://example.org/manifest.webapp',
action: 'write',
src: 'http://test/',
},
{
app: 'http://example.org/manifest.webapp',
action: 'read-yes',
src: 'http://test/',
},
// APP 2
{
app: 'https://example.com/manifest.webapp',
action: 'read-no',
src: 'http://test/',
},
{
app: 'https://example.com/manifest.webapp',
action: 'write',
src: 'http://test/',
},
{
app: 'https://example.com/manifest.webapp',
action: 'read-yes',
src: 'http://test/',
},
// Browser
{
browser: true,
action: 'read-no',
src: 'http://test/',
},
{
browser: true,
action: 'write',
src: 'http://test/',
},
{
browser: true,
action: 'read-yes',
src: 'http://test/',
},
];
function runTest() {
for (var i in gData) {
var iframe = document.createElement('iframe');
var data = gData[i];
if (data.app) {
iframe.setAttribute('mozbrowser', '');
iframe.setAttribute('mozapp', data.app);
} else if (data.browser) {
iframe.setAttribute('mozbrowser', '');
}
if (data.app || data.browser) {
iframe.addEventListener('load', function(e) {
var principal = iframe.contentDocument.nodePrincipal;
switch (data.action) {
case 'read-no':
is(permManager.testPermissionFromPrincipal(principal, gPermName),
Ci.nsIPermissionManager.UNKNOWN_ACTION,
"Permission should not be set yet");
is(permManager.testExactPermissionFromPrincipal(principal, gPermName),
Ci.nsIPermissionManager.UNKNOWN_ACTION,
"Permission should not be set yet");
break;
case 'write':
permManager.addFromPrincipal(principal, gPermName, Ci.nsIPermissionManager.ALLOW_ACTION);
break;
case 'read-yes':
is(permManager.testPermissionFromPrincipal(principal, gPermName),
Ci.nsIPermissionManager.ALLOW_ACTION,
"Permission should be set");
is(permManager.testExactPermissionFromPrincipal(principal, gPermName),
Ci.nsIPermissionManager.ALLOW_ACTION,
"Permission should be set");
break;
default:
ok(false, "shouldn't be there");
}
// Calling removeChild() produces an error that creates failures.
//document.getElementById('content').removeChild(iframe);
i++;
if (i >= gData.length) {
if (previousPrefs.mozBrowserFramesEnabled !== undefined) {
SpecialPowers.setBoolPref('dom.mozBrowserFramesEnabled', previousPrefs.mozBrowserFramesEnabled);
}
SimpleTest.finish();
} else {
gTestRunner.next();
}
});
}
iframe.src = data.src;
document.getElementById('content').appendChild(iframe);
yield;
}
}
var gTestRunner = runTest();
gTestRunner.next();
</script>
</pre>
</body>
</html>

View File

@ -6,7 +6,7 @@
#include "nsISupports.idl"
[scriptable, uuid(cfb08e46-193c-4be7-a467-d7775fb2a31e)]
[scriptable, uuid(5036f0f6-f77b-4168-9d57-a1c0dd66cf02)]
/**
* This interface defines a "permission" object,
* used to specify allowed/blocked objects from
@ -20,16 +20,6 @@ interface nsIPermission : nsISupports
*/
readonly attribute AUTF8String host;
/**
* The id of the app for which the permission is set.
*/
readonly attribute unsigned long appId;
/**
* Whether the permission has been set to a page inside a browser element.
*/
readonly attribute boolean isInBrowserElement;
/**
* a case-sensitive ASCII string, indicating the type of permission
* (e.g., "cookie", "image", etc).

View File

@ -262,13 +262,9 @@ struct Permission
nsCString host, type;
uint32_t capability, expireType;
int64_t expireTime;
uint32_t appId;
bool isInBrowserElement;
Permission() { }
Permission(const nsCString& aHost,
const uint32_t aAppId,
const bool aIsInBrowserElement,
const nsCString& aType,
const uint32_t aCapability,
const uint32_t aExpireType,
@ -276,10 +272,7 @@ struct Permission
type(aType),
capability(aCapability),
expireType(aExpireType),
expireTime(aExpireTime),
appId(aAppId),
isInBrowserElement(aIsInBrowserElement)
{}
expireTime(aExpireTime) { }
};
template<>
@ -292,8 +285,6 @@ struct ParamTraits<Permission>
WriteParam(aMsg, aParam.capability);
WriteParam(aMsg, aParam.expireType);
WriteParam(aMsg, aParam.expireTime);
WriteParam(aMsg, aParam.appId);
WriteParam(aMsg, aParam.isInBrowserElement);
}
static bool Read(const Message* aMsg, void** aIter, Permission* aResult)
@ -302,26 +293,12 @@ struct ParamTraits<Permission>
ReadParam(aMsg, aIter, &aResult->type) &&
ReadParam(aMsg, aIter, &aResult->capability) &&
ReadParam(aMsg, aIter, &aResult->expireType) &&
ReadParam(aMsg, aIter, &aResult->expireTime) &&
ReadParam(aMsg, aIter, &aResult->appId) &&
ReadParam(aMsg, aIter, &aResult->isInBrowserElement);
ReadParam(aMsg, aIter, &aResult->expireTime);
}
static void Log(const Permission& p, std::wstring* l)
static void Log(const Permission& aParam, std::wstring* aLog)
{
l->append(L"(");
LogParam(p.host, l);
l->append(L", ");
LogParam(p.appId, l);
l->append(L", ");
LogParam(p.isInBrowserElement, l);
l->append(L", ");
LogParam(p.capability, l);
l->append(L", ");
LogParam(p.expireTime, l);
l->append(L", ");
LogParam(p.expireType, l);
l->append(L")");
aLog->append(StringPrintf(L"[%s]", aParam.host.get()));
}
};

View File

@ -231,9 +231,6 @@ class Permissions(object):
# Open database and create table
permDB = sqlite3.connect(os.path.join(self._profileDir, "permissions.sqlite"))
cursor = permDB.cursor();
cursor.execute("PRAGMA user_version=3");
# SQL copied from
# http://mxr.mozilla.org/mozilla-central/source/extensions/cookie/nsPermissionManager.cpp
cursor.execute("""CREATE TABLE IF NOT EXISTS moz_hosts (
@ -242,9 +239,7 @@ class Permissions(object):
type TEXT,
permission INTEGER,
expireType INTEGER,
expireTime INTEGER,
appId INTEGER,
isInBrowserElement INTEGER)""")
expireTime INTEGER)""")
for location in locations:
# set the permissions
@ -255,7 +250,7 @@ class Permissions(object):
permission_type = 1
else:
permission_type = 2
cursor.execute("INSERT INTO moz_hosts values(?, ?, ?, ?, 0, 0, 0, 0)",
cursor.execute("INSERT INTO moz_hosts values(?, ?, ?, ?, 0, 0)",
(self._num_permissions, location.host, perm,
permission_type))