Bug 1189070 - Don't discard localhost or IP address entries from the permissions database when migrating, r=ehsan

This commit is contained in:
Michael Layzell 2015-07-31 10:51:45 -07:00
parent 274d644ee1
commit 7022197117
9 changed files with 553 additions and 33 deletions

View File

@ -204,7 +204,7 @@ public:
int64_t aModificationTime) = 0;
};
class UpgradeHostToOriginDBMigration final : public UpgradeHostToOriginHelper {
class MOZ_STACK_CLASS UpgradeHostToOriginDBMigration final : public UpgradeHostToOriginHelper {
public:
UpgradeHostToOriginDBMigration(mozIStorageConnection* aDBConn, int64_t* aID) : mDBConn(aDBConn)
, mID(aID)
@ -256,7 +256,7 @@ private:
int64_t* mID;
};
class UpgradeHostToOriginHostfileImport final : public UpgradeHostToOriginHelper {
class MOZ_STACK_CLASS UpgradeHostToOriginHostfileImport final : public UpgradeHostToOriginHelper {
public:
UpgradeHostToOriginHostfileImport(nsPermissionManager* aPm,
nsPermissionManager::DBOperationType aOperation,
@ -285,6 +285,93 @@ private:
int64_t mID;
};
class MOZ_STACK_CLASS UpgradeIPHostToOriginDB final : public UpgradeHostToOriginHelper {
public:
UpgradeIPHostToOriginDB(mozIStorageConnection* aDBConn, int64_t* aID) : mDBConn(aDBConn)
, mID(aID)
{
mDBConn->CreateStatement(NS_LITERAL_CSTRING(
"INSERT INTO moz_perms"
"(id, origin, type, permission, expireType, expireTime, modificationTime) "
"VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7)"), getter_AddRefs(mStmt));
mDBConn->CreateStatement(NS_LITERAL_CSTRING(
"SELECT id FROM moz_perms WHERE origin = ?1 AND type = ?2"),
getter_AddRefs(mLookupStmt));
}
nsresult
Insert(const nsACString& aOrigin, const nsAFlatCString& aType,
uint32_t aPermission, uint32_t aExpireType, int64_t aExpireTime,
int64_t aModificationTime) final
{
// Every time the migration code wants to insert an origin into
// the database we need to check to see if someone has already
// created a permissions entry for that permission. If they have,
// we don't want to insert a duplicate row.
//
// We can afford to do this lookup unconditionally and not perform
// caching, as a origin type pair should only be attempted to be
// inserted once.
nsresult rv = mLookupStmt->Reset();
NS_ENSURE_SUCCESS(rv, rv);
rv = mLookupStmt->BindUTF8StringByIndex(0, aOrigin);
NS_ENSURE_SUCCESS(rv, rv);
rv = mLookupStmt->BindUTF8StringByIndex(1, aType);
NS_ENSURE_SUCCESS(rv, rv);
// Check if we already have the row in the database, if we do, then
// we don't want to be inserting it again.
bool moreStmts = false;
if (NS_FAILED(mLookupStmt->ExecuteStep(&moreStmts)) || moreStmts) {
mLookupStmt->Reset();
NS_WARNING("A permissions entry was going to be re-migrated, "
"but was already found in the permissions database.");
return NS_OK;
}
// Actually insert the statement into the database.
rv = mStmt->BindInt64ByIndex(0, *mID);
NS_ENSURE_SUCCESS(rv, rv);
rv = mStmt->BindUTF8StringByIndex(1, aOrigin);
NS_ENSURE_SUCCESS(rv, rv);
rv = mStmt->BindUTF8StringByIndex(2, aType);
NS_ENSURE_SUCCESS(rv, rv);
rv = mStmt->BindInt32ByIndex(3, aPermission);
NS_ENSURE_SUCCESS(rv, rv);
rv = mStmt->BindInt32ByIndex(4, aExpireType);
NS_ENSURE_SUCCESS(rv, rv);
rv = mStmt->BindInt64ByIndex(5, aExpireTime);
NS_ENSURE_SUCCESS(rv, rv);
rv = mStmt->BindInt64ByIndex(6, aModificationTime);
NS_ENSURE_SUCCESS(rv, rv);
// Increment the working identifier, as we are about to use this one
(*mID)++;
rv = mStmt->Execute();
NS_ENSURE_SUCCESS(rv, rv);
return NS_OK;
}
private:
nsCOMPtr<mozIStorageStatement> mStmt;
nsCOMPtr<mozIStorageStatement> mLookupStmt;
nsCOMPtr<mozIStorageConnection> mDBConn;
int64_t* mID;
};
nsresult
UpgradeHostToOriginAndInsert(const nsACString& aHost, const nsAFlatCString& aType,
uint32_t aPermission, uint32_t aExpireType, int64_t aExpireTime,
@ -344,10 +431,12 @@ UpgradeHostToOriginAndInsert(const nsACString& aHost, const nsAFlatCString& aTyp
MOZ_ASSERT(tldService); // We should always have a tldService
if (tldService) {
rv = tldService->GetBaseDomainFromHost(aHost, 0, eTLD1);
NS_ENSURE_SUCCESS(rv, rv);
} else {
// We should never hit this branch, but we produce a fake eTLD1
// to avoid crashing in a release build in case we hit this branch
}
if (!tldService || NS_FAILED(rv)) {
// If the lookup on the tldService for the base domain for the host failed,
// that means that we just want to directly use the host as the host name
// for the lookup.
eTLD1 = aHost;
}
@ -446,32 +535,45 @@ UpgradeHostToOriginAndInsert(const nsACString& aHost, const nsAFlatCString& aTyp
// This has a relatively high liklihood of applying the permission to the correct
// origin.
if (!foundHistory) {
rv = NS_NewURI(getter_AddRefs(uri), NS_LITERAL_CSTRING("http://") + aHost);
if (NS_SUCCEEDED(rv)) {
nsCOMPtr<nsIPrincipal> principal;
rv = GetPrincipal(uri, aAppId, aIsInBrowserElement, getter_AddRefs(principal));
NS_ENSURE_SUCCESS(rv, rv);
nsAutoCString hostSegment;
nsCOMPtr<nsIPrincipal> principal;
nsAutoCString origin;
nsAutoCString origin;
rv = principal->GetOrigin(origin);
NS_ENSURE_SUCCESS(rv, rv);
aHelper->Insert(origin, aType, aPermission,
aExpireType, aExpireTime, aModificationTime);
// If this is an ipv6 URI, we need to surround it in '[', ']' before trying to
// parse it as a URI.
if (aHost.FindChar(':') != -1) {
hostSegment.Assign("[");
hostSegment.Append(aHost);
hostSegment.Append("]");
} else {
hostSegment.Assign(aHost);
}
rv = NS_NewURI(getter_AddRefs(uri), NS_LITERAL_CSTRING("https://") + aHost);
if (NS_SUCCEEDED(rv)) {
nsCOMPtr<nsIPrincipal> principal;
rv = GetPrincipal(uri, aAppId, aIsInBrowserElement, getter_AddRefs(principal));
NS_ENSURE_SUCCESS(rv, rv);
nsAutoCString origin;
rv = principal->GetOrigin(origin);
NS_ENSURE_SUCCESS(rv, rv);
// http:// URI default
rv = NS_NewURI(getter_AddRefs(uri), NS_LITERAL_CSTRING("http://") + hostSegment);
NS_ENSURE_SUCCESS(rv, rv);
aHelper->Insert(origin, aType, aPermission,
aExpireType, aExpireTime, aModificationTime);
}
rv = GetPrincipal(uri, aAppId, aIsInBrowserElement, getter_AddRefs(principal));
NS_ENSURE_SUCCESS(rv, rv);
rv = principal->GetOrigin(origin);
NS_ENSURE_SUCCESS(rv, rv);
aHelper->Insert(origin, aType, aPermission,
aExpireType, aExpireTime, aModificationTime);
// https:// URI default
rv = NS_NewURI(getter_AddRefs(uri), NS_LITERAL_CSTRING("https://") + hostSegment);
NS_ENSURE_SUCCESS(rv, rv);
rv = GetPrincipal(uri, aAppId, aIsInBrowserElement, getter_AddRefs(principal));
NS_ENSURE_SUCCESS(rv, rv);
rv = principal->GetOrigin(origin);
NS_ENSURE_SUCCESS(rv, rv);
aHelper->Insert(origin, aType, aPermission,
aExpireType, aExpireTime, aModificationTime);
}
return NS_OK;
@ -614,7 +716,7 @@ nsPermissionManager::AppClearDataObserverInit()
// nsPermissionManager Implementation
#define PERMISSIONS_FILE_NAME "permissions.sqlite"
#define HOSTS_SCHEMA_VERSION 7
#define HOSTS_SCHEMA_VERSION 8
#define HOSTPERM_FILE_NAME "hostperm.1"
@ -1059,8 +1161,8 @@ nsPermissionManager::InitDB(bool aRemoveFile)
// and then back up their old database as moz_perms_v6
nsCOMPtr<mozIStorageStatement> countStmt;
mDBConn->CreateStatement(NS_LITERAL_CSTRING("SELECT COUNT(*) FROM moz_perms"),
getter_AddRefs(countStmt));
rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING("SELECT COUNT(*) FROM moz_perms"),
getter_AddRefs(countStmt));
bool hasResult = false;
if (NS_SUCCEEDED(rv) &&
NS_SUCCEEDED(countStmt->ExecuteStep(&hasResult)) &&
@ -1139,6 +1241,107 @@ nsPermissionManager::InitDB(bool aRemoveFile)
NS_ENSURE_SUCCESS(rv, rv);
}
// fall through to the next upgrade
// The version 7-8 migration is the re-migration of localhost and ip-address
// entries due to errors in the previous version 7 migration which caused
// localhost and ip-address entries to be incorrectly discarded.
// The version 7 migration logic has been corrected, and thus this logic only
// needs to execute if the user is currently on version 7.
case 7:
{
// This migration will be relatively expensive as we need to perform
// database lookups for each origin which we want to insert. Fortunately,
// it shouldn't be too expensive as we only want to insert a small number
// of entries created for localhost or IP addresses.
// We only want to perform the re-migration if moz_hosts is a backup
bool hostsIsBackupExists = false;
mDBConn->TableExists(NS_LITERAL_CSTRING("moz_hosts_is_backup"),
&hostsIsBackupExists);
// Only perform this migration if the original schema version was 7, and
// the moz_hosts table is a backup.
if (dbSchemaVersion == 7 && hostsIsBackupExists) {
nsCOMPtr<nsIEffectiveTLDService> tldService =
do_GetService(NS_EFFECTIVETLDSERVICE_CONTRACTID);
MOZ_ASSERT(tldService); // We should always have a tldService
nsCOMPtr<mozIStorageStatement> stmt;
rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING(
"SELECT host, type, permission, expireType, expireTime, "
"modificationTime, appId, isInBrowserElement FROM moz_hosts"),
getter_AddRefs(stmt));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<mozIStorageStatement> idStmt;
rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING(
"SELECT MAX(id) FROM moz_hosts"), getter_AddRefs(idStmt));
int64_t id = 0;
bool hasResult = false;
if (NS_SUCCEEDED(rv) &&
NS_SUCCEEDED(idStmt->ExecuteStep(&hasResult)) &&
hasResult) {
id = idStmt->AsInt32(0) + 1;
}
nsAutoCString host, type;
uint32_t permission;
uint32_t expireType;
int64_t expireTime;
int64_t modificationTime;
uint32_t appId;
bool isInBrowserElement;
while (NS_SUCCEEDED(stmt->ExecuteStep(&hasResult)) && hasResult) {
// Read in the old row
rv = stmt->GetUTF8String(0, host);
if (NS_WARN_IF(NS_FAILED(rv))) {
continue;
}
nsAutoCString eTLD1;
rv = tldService->GetBaseDomainFromHost(host, 0, eTLD1);
if (NS_SUCCEEDED(rv)) {
// We only care about entries which the tldService can't handle
continue;
}
rv = stmt->GetUTF8String(1, type);
if (NS_WARN_IF(NS_FAILED(rv))) {
continue;
}
permission = stmt->AsInt32(2);
expireType = stmt->AsInt32(3);
expireTime = stmt->AsInt64(4);
modificationTime = stmt->AsInt64(5);
if (NS_WARN_IF(stmt->AsInt64(6) < 0)) {
continue;
}
appId = static_cast<uint32_t>(stmt->AsInt64(6));
isInBrowserElement = static_cast<bool>(stmt->AsInt32(7));
// Perform the meat of the migration by deferring to the
// UpgradeHostToOriginAndInsert function.
UpgradeIPHostToOriginDB upHelper(mDBConn, &id);
rv = UpgradeHostToOriginAndInsert(host, type, permission,
expireType, expireTime,
modificationTime, appId,
isInBrowserElement,
&upHelper);
if (NS_FAILED(rv)) {
NS_WARNING("Unexpected failure when upgrading migrating permission "
"from host to origin");
}
}
}
// Even if we didn't perform the migration, we want to bump the schema
// version to 8.
rv = mDBConn->SetSchemaVersion(8);
NS_ENSURE_SUCCESS(rv, rv);
}
// current version.
case HOSTS_SCHEMA_VERSION:
break;

View File

@ -121,7 +121,7 @@ function run_test() {
// The schema should be upgraded to 6, and a 'modificationTime' column should
// exist with all records having a value of 0.
do_check_eq(connection.schemaVersion, 7);
do_check_eq(connection.schemaVersion, 8);
let select = connection.createStatement("SELECT modificationTime FROM moz_perms")
let numMigrated = 0;

View File

@ -85,6 +85,9 @@ add_task(function test() {
insertHost("bar.ca", "B", 1, 0, 0, 0, 0, false),
insertHost("bar.ca", "B", 1, 0, 0, 0, 1000, false),
insertHost("bar.ca", "A", 1, 0, 0, 0, 1000, true),
insertHost("localhost", "A", 1, 0, 0, 0, 0, false),
insertHost("127.0.0.1", "A", 1, 0, 0, 0, 0, false),
insertHost("192.0.2.235", "A", 1, 0, 0, 0, 0, false),
insertHost("file:///some/path/to/file.html", "A", 1, 0, 0, 0, 0, false),
insertHost("file:///another/file.html", "A", 1, 0, 0, 0, 0, false),
insertHost("moz-nullprincipal:{8695105a-adbe-4e4e-8083-851faa5ca2d7}", "A", 1, 0, 0, 0, 0, false),
@ -139,6 +142,14 @@ add_task(function test() {
// following entries
["ftp://sub.foo.com:8000", "B", 1, 0, 0],
["ftp://subber.sub.foo.com:8000", "B", 1, 0, 0],
// Make sure that we also support localhost, and IP addresses
["http://localhost", "A", 1, 0, 0],
["https://localhost", "A", 1, 0, 0],
["http://127.0.0.1", "A", 1, 0, 0],
["https://127.0.0.1", "A", 1, 0, 0],
["http://192.0.2.235", "A", 1, 0, 0],
["https://192.0.2.235", "A", 1, 0, 0],
];
let found = expected.map((it) => 0);

View File

@ -122,6 +122,9 @@ add_task(function test() {
insertHost("bar.ca", "B", 1, 0, 0, 0, 0, false),
insertHost("bar.ca", "B", 1, 0, 0, 0, 1000, false),
insertHost("bar.ca", "A", 1, 0, 0, 0, 1000, true),
insertHost("localhost", "A", 1, 0, 0, 0, 0, false),
insertHost("127.0.0.1", "A", 1, 0, 0, 0, 0, false),
insertHost("263.123.555.676", "A", 1, 0, 0, 0, 0, false),
insertHost("file:///some/path/to/file.html", "A", 1, 0, 0, 0, 0, false),
insertHost("file:///another/file.html", "A", 1, 0, 0, 0, 0, false),
insertHost("moz-nullprincipal:{8695105a-adbe-4e4e-8083-851faa5ca2d7}", "A", 1, 0, 0, 0, 0, false),
@ -160,6 +163,14 @@ add_task(function test() {
["https://bar.ca^appId=1000&inBrowser=1", "A", 1, 0, 0],
["file:///some/path/to/file.html", "A", 1, 0, 0],
["file:///another/file.html", "A", 1, 0, 0],
// Make sure that we also support localhost, and IP addresses
["http://localhost", "A", 1, 0, 0],
["https://localhost", "A", 1, 0, 0],
["http://127.0.0.1", "A", 1, 0, 0],
["https://127.0.0.1", "A", 1, 0, 0],
["http://263.123.555.676", "A", 1, 0, 0],
["https://263.123.555.676", "A", 1, 0, 0],
];
let found = expected.map((it) => 0);

View File

@ -139,6 +139,9 @@ add_task(function test() {
insertHost("bar.ca", "B", 1, 0, 0, 0, 0, false),
insertHost("bar.ca", "B", 1, 0, 0, 0, 1000, false),
insertHost("bar.ca", "A", 1, 0, 0, 0, 1000, true),
insertHost("localhost", "A", 1, 0, 0, 0, 0, false),
insertHost("127.0.0.1", "A", 1, 0, 0, 0, 0, false),
insertHost("192.0.2.235", "A", 1, 0, 0, 0, 0, false),
insertHost("file:///some/path/to/file.html", "A", 1, 0, 0, 0, 0, false),
insertHost("file:///another/file.html", "A", 1, 0, 0, 0, 0, false),
insertHost("moz-nullprincipal:{8695105a-adbe-4e4e-8083-851faa5ca2d7}", "A", 1, 0, 0, 0, 0, false),
@ -193,6 +196,14 @@ add_task(function test() {
// following entries
["ftp://sub.foo.com:8000", "B", 1, 0, 0],
["ftp://subber.sub.foo.com:8000", "B", 1, 0, 0],
// Make sure that we also support localhost, and IP addresses
["http://localhost", "A", 1, 0, 0],
["https://localhost", "A", 1, 0, 0],
["http://127.0.0.1", "A", 1, 0, 0],
["https://127.0.0.1", "A", 1, 0, 0],
["http://192.0.2.235", "A", 1, 0, 0],
["https://192.0.2.235", "A", 1, 0, 0],
];
let found = expected.map((it) => 0);

View File

@ -75,6 +75,9 @@ add_task(function test() {
insertOrigin("https://foo.com", "A", 2, 0, 0, 0),
insertOrigin("http://foo.com", "A", 2, 0, 0, 0),
insertOrigin("http://foo.com^appId=1000&inBrowser=1", "A", 2, 0, 0, 0),
insertOrigin("http://127.0.0.1", "B", 2, 0, 0, 0),
insertOrigin("http://localhost", "B", 2, 0, 0, 0),
];
let created4 = []; // Didn't create any v4 entries, so the DB should be empty
@ -88,7 +91,10 @@ add_task(function test() {
let expected = [
["https://foo.com", "A", 2, 0, 0, 0],
["http://foo.com", "A", 2, 0, 0, 0],
["http://foo.com^appId=1000&inBrowser=1", "A", 2, 0, 0, 0]
["http://foo.com^appId=1000&inBrowser=1", "A", 2, 0, 0, 0],
["http://127.0.0.1", "B", 2, 0, 0, 0],
["http://localhost", "B", 2, 0, 0, 0],
];
let found = expected.map((it) => 0);

View File

@ -139,6 +139,9 @@ add_task(function test() {
insertHost("bar.ca", "B", 1, 0, 0, 0, 0, false),
insertHost("bar.ca", "B", 1, 0, 0, 0, 1000, false),
insertHost("bar.ca", "A", 1, 0, 0, 0, 1000, true),
insertHost("localhost", "A", 1, 0, 0, 0, 0, false),
insertHost("127.0.0.1", "A", 1, 0, 0, 0, 0, false),
insertHost("192.0.2.235", "A", 1, 0, 0, 0, 0, false),
insertHost("file:///some/path/to/file.html", "A", 1, 0, 0, 0, 0, false),
insertHost("file:///another/file.html", "A", 1, 0, 0, 0, 0, false),
insertHost("moz-nullprincipal:{8695105a-adbe-4e4e-8083-851faa5ca2d7}", "A", 1, 0, 0, 0, 0, false),
@ -193,6 +196,14 @@ add_task(function test() {
// following entries
["ftp://sub.foo.com:8000", "B", 1, 0, 0],
["ftp://subber.sub.foo.com:8000", "B", 1, 0, 0],
// Make sure that we also support localhost, and IP addresses
["http://localhost", "A", 1, 0, 0],
["https://localhost", "A", 1, 0, 0],
["http://127.0.0.1", "A", 1, 0, 0],
["https://127.0.0.1", "A", 1, 0, 0],
["http://192.0.2.235", "A", 1, 0, 0],
["https://192.0.2.235", "A", 1, 0, 0],
];
let found = expected.map((it) => 0);

View File

@ -0,0 +1,266 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
XPCOMUtils.defineLazyModuleGetter(this, "PlacesTestUtils",
"resource://testing-common/PlacesTestUtils.jsm");
let PERMISSIONS_FILE_NAME = "permissions.sqlite";
function GetPermissionsFile(profile)
{
let file = profile.clone();
file.append(PERMISSIONS_FILE_NAME);
return file;
}
function run_test() {
run_next_test();
}
add_task(function test() {
/* Create and set up the permissions database */
let profile = do_get_profile();
let db = Services.storage.openDatabase(GetPermissionsFile(profile));
db.schemaVersion = 7;
/*
* V5 table
*/
db.executeSimpleSQL(
"CREATE TABLE moz_perms (" +
" id INTEGER PRIMARY KEY" +
",origin TEXT" +
",type TEXT" +
",permission INTEGER" +
",expireType INTEGER" +
",expireTime INTEGER" +
",modificationTime INTEGER" +
")");
let stmt6Insert = db.createStatement(
"INSERT INTO moz_perms (" +
"id, origin, type, permission, expireType, expireTime, modificationTime" +
") VALUES (" +
":id, :origin, :type, :permission, :expireType, :expireTime, :modificationTime" +
")");
/*
* V4 table
*/
db.executeSimpleSQL(
"CREATE TABLE moz_hosts (" +
" id INTEGER PRIMARY KEY" +
",host TEXT" +
",type TEXT" +
",permission INTEGER" +
",expireType INTEGER" +
",expireTime INTEGER" +
",modificationTime INTEGER" +
",appId INTEGER" +
",isInBrowserElement INTEGER" +
")");
let stmtInsert = db.createStatement(
"INSERT INTO moz_hosts (" +
"id, host, type, permission, expireType, expireTime, modificationTime, appId, isInBrowserElement" +
") VALUES (" +
":id, :host, :type, :permission, :expireType, :expireTime, :modificationTime, :appId, :isInBrowserElement" +
")");
/*
* The v4 table is a backup
*/
db.executeSimpleSQL("CREATE TABLE moz_hosts_is_backup (dummy INTEGER PRIMARY KEY)");
let id = 0;
function insertOrigin(origin, type, permission, expireType, expireTime, modificationTime) {
let thisId = id++;
stmt6Insert.bindByName("id", thisId);
stmt6Insert.bindByName("origin", origin);
stmt6Insert.bindByName("type", type);
stmt6Insert.bindByName("permission", permission);
stmt6Insert.bindByName("expireType", expireType);
stmt6Insert.bindByName("expireTime", expireTime);
stmt6Insert.bindByName("modificationTime", modificationTime);
stmt6Insert.execute();
return {
id: thisId,
origin: origin,
type: type,
permission: permission,
expireType: expireType,
expireTime: expireTime,
modificationTime: modificationTime
};
}
function insertHost(host, type, permission, expireType, expireTime, modificationTime, appId, isInBrowserElement) {
let thisId = id++;
stmtInsert.bindByName("id", thisId);
stmtInsert.bindByName("host", host);
stmtInsert.bindByName("type", type);
stmtInsert.bindByName("permission", permission);
stmtInsert.bindByName("expireType", expireType);
stmtInsert.bindByName("expireTime", expireTime);
stmtInsert.bindByName("modificationTime", modificationTime);
stmtInsert.bindByName("appId", appId);
stmtInsert.bindByName("isInBrowserElement", isInBrowserElement);
stmtInsert.execute();
return {
id: thisId,
host: host,
type: type,
permission: permission,
expireType: expireType,
expireTime: expireTime,
modificationTime: modificationTime,
appId: appId,
isInBrowserElement: isInBrowserElement
};
}
let created7 = [
insertOrigin("https://foo.com", "A", 2, 0, 0, 0),
insertOrigin("http://foo.com", "A", 2, 0, 0, 0),
insertOrigin("http://foo.com^appId=1000&inBrowser=1", "A", 2, 0, 0, 0),
insertOrigin("https://192.0.2.235", "A", 2, 0, 0),
];
// Add some rows to the database
let created = [
insertHost("foo.com", "A", 1, 0, 0, 0, 0, false),
insertHost("foo.com", "C", 1, 0, 0, 0, 0, false),
insertHost("foo.com", "A", 1, 0, 0, 0, 1000, false),
insertHost("foo.com", "A", 1, 0, 0, 0, 2000, true),
insertHost("sub.foo.com", "B", 1, 0, 0, 0, 0, false),
insertHost("subber.sub.foo.com", "B", 1, 0, 0, 0, 0, false),
insertHost("bar.ca", "B", 1, 0, 0, 0, 0, false),
insertHost("bar.ca", "B", 1, 0, 0, 0, 1000, false),
insertHost("bar.ca", "A", 1, 0, 0, 0, 1000, true),
insertHost("localhost", "A", 1, 0, 0, 0, 0, false),
insertHost("127.0.0.1", "A", 1, 0, 0, 0, 0, false),
insertHost("192.0.2.235", "A", 1, 0, 0, 0, 0, false),
// Although ipv6 addresses are written with [] around the IP address,
// the .host property doesn't contain these []s, which means that we
// write it like this
insertHost("2001:db8::ff00:42:8329", "C", 1, 0, 0, 0, 0, false),
insertHost("file:///some/path/to/file.html", "A", 1, 0, 0, 0, 0, false),
insertHost("file:///another/file.html", "A", 1, 0, 0, 0, 0, false),
insertHost("moz-nullprincipal:{8695105a-adbe-4e4e-8083-851faa5ca2d7}", "A", 1, 0, 0, 0, 0, false),
insertHost("moz-nullprincipal:{12ahjksd-akjs-asd3-8393-asdu2189asdu}", "B", 1, 0, 0, 0, 0, false),
insertHost("<file>", "A", 1, 0, 0, 0, 0, false),
insertHost("<file>", "B", 1, 0, 0, 0, 0, false),
];
// CLose the db connection
stmtInsert.finalize();
db.close();
stmtInsert = null;
db = null;
let expected = [
// We should have kept the previously migrated entries
["https://foo.com", "A", 2, 0, 0, 0],
["http://foo.com", "A", 2, 0, 0, 0],
["http://foo.com^appId=1000&inBrowser=1", "A", 2, 0, 0, 0],
// Make sure that we also support localhost, and IP addresses
["https://localhost:8080", "A", 1, 0, 0],
["ftp://127.0.0.1:8080", "A", 1, 0, 0],
["http://[2001:db8::ff00:42:8329]", "C", 1, 0, 0],
["https://[2001:db8::ff00:42:8329]", "C", 1, 0, 0],
["http://192.0.2.235", "A", 1, 0, 0],
// There should only be one entry of this type in the database
["https://192.0.2.235", "A", 2, 0, 0],
];
let found = expected.map((it) => 0);
// Add some places to the places database
yield PlacesTestUtils.addVisits(Services.io.newURI("https://foo.com/some/other/subdirectory", null, null));
yield PlacesTestUtils.addVisits(Services.io.newURI("ftp://some.subdomain.of.foo.com:8000/some/subdirectory", null, null));
yield PlacesTestUtils.addVisits(Services.io.newURI("ftp://127.0.0.1:8080", null, null));
yield PlacesTestUtils.addVisits(Services.io.newURI("https://localhost:8080", null, null));
// Force initialization of the nsPermissionManager
let enumerator = Services.perms.enumerator;
while (enumerator.hasMoreElements()) {
let permission = enumerator.getNext().QueryInterface(Ci.nsIPermission);
let isExpected = false;
expected.forEach((it, i) => {
if (permission.principal.origin == it[0] &&
permission.type == it[1] &&
permission.capability == it[2] &&
permission.expireType == it[3] &&
permission.expireTime == it[4]) {
isExpected = true;
found[i]++;
}
});
do_check_true(isExpected,
"Permission " + (isExpected ? "should" : "shouldn't") +
" be in permission database: " +
permission.principal.origin + ", " +
permission.type + ", " +
permission.capability + ", " +
permission.expireType + ", " +
permission.expireTime);
}
found.forEach((count, i) => {
do_check_true(count == 1, "Expected count = 1, got count = " + count + " for permission " + expected[i]);
});
// Check to make sure that all of the tables which we care about are present
{
let db = Services.storage.openDatabase(GetPermissionsFile(profile));
do_check_true(db.tableExists("moz_perms"));
do_check_true(db.tableExists("moz_hosts"));
do_check_true(db.tableExists("moz_hosts_is_backup"));
do_check_false(db.tableExists("moz_perms_v6"));
let mozHostsStmt = db.createStatement("SELECT " +
"host, type, permission, expireType, expireTime, " +
"modificationTime, appId, isInBrowserElement " +
"FROM moz_hosts WHERE id = :id");
// Check that the moz_hosts table still contains the correct values.
created.forEach((it) => {
mozHostsStmt.reset();
mozHostsStmt.bindByName("id", it.id);
mozHostsStmt.executeStep();
do_check_eq(mozHostsStmt.getUTF8String(0), it.host);
do_check_eq(mozHostsStmt.getUTF8String(1), it.type);
do_check_eq(mozHostsStmt.getInt64(2), it.permission);
do_check_eq(mozHostsStmt.getInt64(3), it.expireType);
do_check_eq(mozHostsStmt.getInt64(4), it.expireTime);
do_check_eq(mozHostsStmt.getInt64(5), it.modificationTime);
do_check_eq(mozHostsStmt.getInt64(6), it.appId);
do_check_eq(mozHostsStmt.getInt64(7), it.isInBrowserElement);
});
// Check that there are the right number of values
let mozHostsCount = db.createStatement("SELECT count(*) FROM moz_hosts");
mozHostsCount.executeStep();
do_check_eq(mozHostsCount.getInt64(0), created.length);
// Check that there are the right number of values in the permissions database
let mozPermsCount = db.createStatement("SELECT count(*) FROM moz_perms");
mozPermsCount.executeStep();
do_check_eq(mozPermsCount.getInt64(0), expected.length);
db.close();
}
});

View File

@ -43,3 +43,4 @@ skip-if = debug == true
[test_permmanager_migrate_6-7a.js]
[test_permmanager_migrate_6-7b.js]
[test_permmanager_migrate_4-7_no_history.js]
[test_permmanager_migrate_7-8.js]