Bug 1339081 - Part 6: Fix unknown file handling; r=asuth

This commit is contained in:
Jan Varga 2017-03-06 18:39:38 +01:00
Родитель 61fe32371f
Коммит f0b8133f92
4 изменённых файлов: 278 добавлений и 40 удалений

Просмотреть файл

@ -77,6 +77,10 @@
#define ASSERT_UNLESS_FUZZING(...) MOZ_ASSERT(false, __VA_ARGS__)
#endif
#define UNKNOWN_FILE_WARNING(_leafName) \
QM_WARNING("Something (%s) in the directory that doesn't belong!", \
NS_ConvertUTF16toUTF8(leafName).get())
// The amount of time, in milliseconds, that our IO thread will stay alive
// after the last event it processes.
#define DEFAULT_THREAD_TIMEOUT_MS 30000
@ -3753,8 +3757,7 @@ QuotaManager::InitializeRepository(PersistenceType aPersistenceType)
continue;
}
QM_WARNING("Something (%s) in the repository that doesn't belong!",
NS_ConvertUTF16toUTF8(leafName).get());
UNKNOWN_FILE_WARNING(leafName);
return NS_ERROR_UNEXPECTED;
}
@ -3849,22 +3852,26 @@ QuotaManager::InitializeOrigin(PersistenceType aPersistenceType,
nsCOMPtr<nsIFile> file = do_QueryInterface(entry);
NS_ENSURE_TRUE(file, NS_NOINTERFACE);
nsString leafName;
rv = file->GetLeafName(leafName);
NS_ENSURE_SUCCESS(rv, rv);
if (leafName.EqualsLiteral(METADATA_FILE_NAME) ||
leafName.EqualsLiteral(METADATA_V2_FILE_NAME) ||
leafName.EqualsLiteral(DSSTORE_FILE_NAME)) {
continue;
}
bool isDirectory;
rv = file->IsDirectory(&isDirectory);
NS_ENSURE_SUCCESS(rv, rv);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
nsString leafName;
rv = file->GetLeafName(leafName);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
if (!isDirectory) {
NS_WARNING("Unknown file found!");
if (leafName.EqualsLiteral(METADATA_FILE_NAME) ||
leafName.EqualsLiteral(METADATA_V2_FILE_NAME) ||
leafName.EqualsLiteral(DSSTORE_FILE_NAME)) {
continue;
}
UNKNOWN_FILE_WARNING(leafName);
return NS_ERROR_UNEXPECTED;
}
@ -3875,7 +3882,7 @@ QuotaManager::InitializeOrigin(PersistenceType aPersistenceType,
Client::Type clientType;
rv = Client::TypeFromText(leafName, clientType);
if (NS_FAILED(rv)) {
NS_WARNING("Unknown directory found!");
UNKNOWN_FILE_WARNING(leafName);
return NS_ERROR_UNEXPECTED;
}
@ -6051,25 +6058,34 @@ GetUsageOp::AddToUsage(QuotaManager* aQuotaManager,
nsCOMPtr<nsIFile> file = do_QueryInterface(entry);
NS_ENSURE_TRUE(file, NS_NOINTERFACE);
nsString leafName;
rv = file->GetLeafName(leafName);
NS_ENSURE_SUCCESS(rv, rv);
if (leafName.EqualsLiteral(METADATA_FILE_NAME) ||
leafName.EqualsLiteral(METADATA_V2_FILE_NAME) ||
leafName.EqualsLiteral(DSSTORE_FILE_NAME)) {
continue;
bool isDirectory;
rv = file->IsDirectory(&isDirectory);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
if (!initialized) {
bool isDirectory;
rv = file->IsDirectory(&isDirectory);
NS_ENSURE_SUCCESS(rv, rv);
nsString leafName;
rv = file->GetLeafName(leafName);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
if (!isDirectory) {
NS_WARNING("Unknown file found!");
if (!isDirectory) {
// We are maintaining existing behavior here (failing if the origin is
// not yet initialized or just continuing otherwise).
// This can possibly be used by developers to add temporary backups into
// origin directories without losing get usage functionality.
if (leafName.EqualsLiteral(METADATA_FILE_NAME) ||
leafName.EqualsLiteral(METADATA_V2_FILE_NAME) ||
leafName.EqualsLiteral(DSSTORE_FILE_NAME)) {
continue;
}
UNKNOWN_FILE_WARNING(leafName);
if (!initialized) {
return NS_ERROR_UNEXPECTED;
}
continue;
}
if (MaybeRemoveCorruptDirectory(leafName, file)) {
@ -6079,7 +6095,7 @@ GetUsageOp::AddToUsage(QuotaManager* aQuotaManager,
Client::Type clientType;
rv = Client::TypeFromText(leafName, clientType);
if (NS_FAILED(rv)) {
NS_WARNING("Unknown directory found!");
UNKNOWN_FILE_WARNING(leafName);
if (!initialized) {
return NS_ERROR_UNEXPECTED;
}
@ -6509,9 +6525,9 @@ ClearRequestBase::DeleteFiles(QuotaManager* aQuotaManager,
}
if (!isDirectory) {
// Unknown files during clearing are allowed. Just warn if we find them.
if (!leafName.EqualsLiteral(DSSTORE_FILE_NAME)) {
QM_WARNING("Something (%s) in the repository that doesn't belong!",
NS_ConvertUTF16toUTF8(leafName).get());
UNKNOWN_FILE_WARNING(leafName);
}
continue;
}
@ -7288,10 +7304,9 @@ CreateOrUpgradeDirectoryMetadataHelper::CreateOrUpgradeMetadataFiles()
continue;
}
} else {
// Unknown files during upgrade are allowed. Just warn if we find them.
if (!leafName.EqualsLiteral(DSSTORE_FILE_NAME)) {
QM_WARNING("Something (%s) in the storage directory that doesn't belong!",
NS_ConvertUTF16toUTF8(leafName).get());
UNKNOWN_FILE_WARNING(leafName);
}
continue;
}
@ -7671,10 +7686,9 @@ UpgradeDirectoryMetadataFrom1To2Helper::UpgradeMetadataFiles()
return rv;
}
// Unknown files during upgrade are allowed. Just warn if we find them.
if (!leafName.EqualsLiteral(DSSTORE_FILE_NAME)) {
QM_WARNING("Something (%s) in the storage directory that doesn't belong!",
NS_ConvertUTF16toUTF8(leafName).get());
UNKNOWN_FILE_WARNING(leafName);
}
continue;
}

Просмотреть файл

@ -3,9 +3,10 @@
* http://creativecommons.org/publicdomain/zero/1.0/
*/
var { 'classes': Cc, 'interfaces': Ci, 'utils': Cu } = Components;
const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
const NS_OK = 0x0;
const NS_OK = Cr.NS_OK;
const NS_ERROR_UNEXPECTED = Cr.NS_ERROR_UNEXPECTED;
function is(a, b, msg)
{
@ -80,6 +81,16 @@ function init(callback)
return request;
}
function initOrigin(principal, persistence, callback)
{
let request =
SpecialPowers._getQuotaManager().initStoragesForPrincipal(principal,
persistence);
request.callback = callback;
return request;
}
function initChromeOrigin(persistence, callback)
{
let principal = Cc["@mozilla.org/systemprincipal;1"]
@ -100,6 +111,28 @@ function clear(callback)
return request;
}
function clearOrigin(principal, persistence, callback)
{
let request =
SpecialPowers._getQuotaManager().clearStoragesForPrincipal(principal,
persistence);
request.callback = callback;
return request;
}
function clearChromeOrigin(callback)
{
let principal = Cc["@mozilla.org/systemprincipal;1"]
.createInstance(Ci.nsIPrincipal);
let request =
SpecialPowers._getQuotaManager().clearStoragesForPrincipal(principal,
"persistent");
request.callback = callback;
return request;
}
function reset(callback)
{
let request = SpecialPowers._getQuotaManager().reset();
@ -199,6 +232,16 @@ function getUsage(usageHandler)
return request;
}
function getPrincipal(url)
{
let uri = Cc["@mozilla.org/network/io-service;1"]
.getService(Ci.nsIIOService)
.newURI(url);
let ssm = Cc["@mozilla.org/scriptsecuritymanager;1"]
.getService(Ci.nsIScriptSecurityManager);
return ssm.createCodebasePrincipal(uri, {});
}
var SpecialPowers = {
getBoolPref: function(prefName) {
return this._getPrefs().getBoolPref(prefName);

Просмотреть файл

@ -0,0 +1,180 @@
/**
* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/
*/
var testGenerator = testSteps();
function* testSteps()
{
const unknownRepoFiles = [
{
path: "storage/persistent/foo.bar",
dir: false
},
{
path: "storage/permanent/foo.bar",
dir: false
}
];
const exampleUrl = "http://example.com";
const unknownRepoFile = {
path: "storage/default/foo.bar",
dir: false
};
const unknownOriginFiles = [
{
path: "storage/permanent/chrome/foo.bar",
dir: false
},
{
path: "storage/permanent/chrome/foo",
dir: true
}
];
function createFile(unknownFile) {
let file = getRelativeFile(unknownFile.path);
if (unknownFile.dir) {
file.create(Ci.nsIFile.DIRECTORY_TYPE, parseInt("0755", 8));
} else {
file.create(Ci.nsIFile.NORMAL_FILE_TYPE, parseInt("0644", 8));
}
return file;
}
let file, request;
info("Stage 1 - Testing unknown repo files found during upgrades");
for (let unknownFile of unknownRepoFiles) {
info("Creating unknown file");
file = createFile(unknownFile);
info("Initializing");
request = init(continueToNextStepSync)
yield undefined;
ok(request.resultCode == NS_OK, "Initialization succeeded");
info("Clearing");
request = clear(continueToNextStepSync);
yield undefined;
ok(request.resultCode == NS_OK, "Clearing succeeded");
}
info("Stage 2 - Testing unknown repo file found during tempo storage init");
info("Initializing");
request = init(continueToNextStepSync)
yield undefined;
ok(request.resultCode == NS_OK, "Initialization succeeded");
info("Creating unknown file");
file = createFile(unknownRepoFile);
info("Initializing origin");
let principal = getPrincipal(exampleUrl);
request = initOrigin(principal, "default", continueToNextStepSync);
yield undefined;
ok(request.resultCode == NS_ERROR_UNEXPECTED, "Initialization failed");
info("Clearing origin");
request = clearOrigin(principal, "default", continueToNextStepSync);
yield undefined;
ok(request.resultCode == NS_OK, "Clearing succeeded");
info("Clearing");
request = clear(continueToNextStepSync);
yield undefined;
ok(request.resultCode == NS_OK, "Clearing succeeded");
info("Stage 3 - Testing unknown origin files found during origin init");
info("Initializing");
request = init(continueToNextStepSync)
yield undefined;
ok(request.resultCode == NS_OK, "Initialization succeeded");
for (let unknownFile of unknownOriginFiles) {
info("Creating unknown file");
file = createFile(unknownFile);
info("Initializing origin");
request = initChromeOrigin("persistent", continueToNextStepSync);
yield undefined;
ok(request.resultCode == NS_ERROR_UNEXPECTED, "Initialization failed");
info("Getting usage");
request = getUsage(continueToNextStepSync);
yield undefined;
ok(request.resultCode == NS_ERROR_UNEXPECTED, "Get usage failed");
file.remove(/* recursive */ false);
info("Getting usage");
request = getUsage(continueToNextStepSync);
yield undefined;
ok(request.resultCode == NS_OK, "Get usage succeeded");
info("Initializing origin");
request = initChromeOrigin("persistent", continueToNextStepSync);
yield undefined;
ok(request.resultCode == NS_OK, "Initialization succeeded");
file = createFile(unknownFile);
info("Getting usage");
request = getUsage(continueToNextStepSync);
yield undefined;
ok(request.resultCode == NS_OK, "Get usage succeeded");
info("Clearing origin");
request = clearChromeOrigin(continueToNextStepSync);
yield undefined;
ok(request.resultCode == NS_OK, "Clearing succeeded");
}
info("Clearing");
request = clear(continueToNextStepSync);
yield undefined;
ok(request.resultCode == NS_OK, "Clearing succeeded");
finishTest();
}

Просмотреть файл

@ -8,3 +8,4 @@ support-files =
basics_profile.zip
[test_basics.js]
[test_unknownFiles.js]