зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1339081 - Part 6: Fix unknown file handling; r=asuth
This commit is contained in:
Родитель
61fe32371f
Коммит
f0b8133f92
|
@ -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]
|
||||
|
|
Загрузка…
Ссылка в новой задаче