Bug 1056939 - indexedDB.open fails for certain database names - part 2; r=bent
--- a/dom/indexedDB/ActorsParent.cpp
+++ b/dom/indexedDB/ActorsParent.cpp
@@ -9151,28 +9151,28 @@ QuotaClient::NoteBackgroundThread(nsIEve
}
mozilla::dom::quota::Client::Type
QuotaClient::GetType()
{
return QuotaClient::IDB;
}
+struct FileManagerInitInfo
+{
+ nsCOMPtr<nsIFile> mDirectory;
+ nsCOMPtr<nsIFile> mDatabaseFile;
+};
+
nsresult
QuotaClient::InitOrigin(PersistenceType aPersistenceType,
const nsACString& aGroup,
const nsACString& aOrigin,
UsageInfo* aUsageInfo)
{
- struct FileManagerInitInfo
- {
- nsCOMPtr<nsIFile> mDirectory;
- nsCOMPtr<nsIFile> mDatabaseFile;
- };
-
AssertIsOnIOThread();
nsCOMPtr<nsIFile> directory;
nsresult rv =
GetDirectory(aPersistenceType, aOrigin, getter_AddRefs(directory));
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
@@ -9208,38 +9208,40 @@ QuotaClient::InitOrigin(PersistenceType
MOZ_ASSERT(file);
nsString leafName;
rv = file->GetLeafName(leafName);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
- if (StringEndsWith(leafName, NS_LITERAL_STRING(".sqlite-journal"))) {
- continue;
- }
-
- if (leafName.EqualsLiteral(DSSTORE_FILE_NAME)) {
- continue;
- }
bool isDirectory;
rv = file->IsDirectory(&isDirectory);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
if (isDirectory) {
if (!StringEndsWith(leafName, filesSuffix) ||
!validSubdirs.GetEntry(leafName)) {
subdirsToProcess.AppendElement(leafName);
}
continue;
}
+ // Skip SQLite and Desktop Service Store (.DS_Store) files.
+ // Desktop Service Store file is only used on Mac OS X, but the profile
+ // can be shared across different operating systems, so we check it on
+ // all platforms.
+ if (StringEndsWith(leafName, NS_LITERAL_STRING(".sqlite-journal")) ||
+ leafName.EqualsLiteral(DSSTORE_FILE_NAME)) {
+ continue;
+ }
+
nsDependentSubstring dbBaseFilename;
if (!GetDatabaseBaseFilename(leafName, dbBaseFilename)) {
unknownFiles.AppendElement(file);
continue;
}
nsString fmDirectoryBaseName = dbBaseFilename + filesSuffix;
@@ -9277,26 +9279,24 @@ QuotaClient::InitOrigin(PersistenceType
continue;
}
// The directory didn't have the right suffix but we might need to rename
// it. Check to see if we have a database that references this directory.
nsString subdirNameWithSuffix = subdirName + filesSuffix;
if (!validSubdirs.GetEntry(subdirNameWithSuffix)) {
-#ifdef XP_WIN
// Windows doesn't allow a directory to end with a dot ('.'), so we have
// to check that possibility here too.
+ // We do this on all platforms, because the origin directory may have
+ // been created on Windows and now accessed on different OS.
subdirNameWithSuffix = subdirName + NS_LITERAL_STRING(".") + filesSuffix;
if (NS_WARN_IF(!validSubdirs.GetEntry(subdirNameWithSuffix))) {
return NS_ERROR_UNEXPECTED;
}
-#else
- return NS_ERROR_UNEXPECTED;
-#endif
}
// We do have a database that uses this directory so we should rename it
// now. However, first check to make sure that we're not overwriting
// something else.
nsCOMPtr<nsIFile> subdir;
rv = directory->Clone(getter_AddRefs(subdir));
if (NS_WARN_IF(NS_FAILED(rv))) {
@@ -9334,39 +9334,16 @@ QuotaClient::InitOrigin(PersistenceType
MOZ_ASSERT(isDirectory);
rv = subdir->RenameTo(nullptr, subdirNameWithSuffix);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
}
- for (uint32_t count = unknownFiles.Length(), i = 0; i < count; i++) {
- nsCOMPtr<nsIFile>& unknownFile = unknownFiles[i];
-
- // Some temporary SQLite files could disappear, so we have to check if the
- // unknown file still exists.
- bool exists;
- rv = unknownFile->Exists(&exists);
- if (NS_WARN_IF(NS_FAILED(rv))) {
- return rv;
- }
-
- if (exists) {
- nsString leafName;
- unknownFile->GetLeafName(leafName);
-
- // The journal file may exists even after db has been correctly opened.
- if (NS_WARN_IF(!StringEndsWith(leafName,
- NS_LITERAL_STRING(".sqlite-journal")))) {
- return NS_ERROR_UNEXPECTED;
- }
- }
- }
-
for (uint32_t count = initInfos.Length(), i = 0; i < count; i++) {
FileManagerInitInfo& initInfo = initInfos[i];
MOZ_ASSERT(initInfo.mDirectory);
MOZ_ASSERT(initInfo.mDatabaseFile);
rv = FileManager::InitDirectory(initInfo.mDirectory,
initInfo.mDatabaseFile,
aPersistenceType,
@@ -9392,16 +9369,33 @@ QuotaClient::InitOrigin(PersistenceType
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
aUsageInfo->AppendToFileUsage(usage);
}
}
+ // We have to do this after file manager initialization.
+ for (uint32_t count = unknownFiles.Length(), i = 0; i < count; i++) {
+ nsCOMPtr<nsIFile>& unknownFile = unknownFiles[i];
+
+ // Some temporary SQLite files could disappear during file manager
+ // initialization, so we have to check if the unknown file still exists.
+ bool exists;
+ rv = unknownFile->Exists(&exists);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
+
+ if (exists) {
+ return NS_ERROR_UNEXPECTED;
+ }
+ }
+
return NS_OK;
}
nsresult
QuotaClient::GetUsageForOrigin(PersistenceType aPersistenceType,
const nsACString& aGroup,
const nsACString& aOrigin,
UsageInfo* aUsageInfo)
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..db3cfe62464e8f50d11664578c879c8af7c45014
GIT binary patch
literal 8029
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
DhVkiI
new file mode 100644
--- /dev/null
+++ b/dom/indexedDB/test/unit/test_bug1056939.js
@@ -0,0 +1,131 @@
+/**
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+var testGenerator = testSteps();
+
+function testSteps()
+{
+ const dbName1 = "upgrade_test";
+ const dbName2 = "testing.foobar";
+ const dbName3 = "xxxxxxx.xxxxxx";
+
+ clearAllDatabases(continueToNextStepSync);
+ yield undefined;
+
+ installPackagedProfile("bug1056939");
+
+ let request = indexedDB.open(dbName1, 1);
+ request.onerror = errorHandler;
+ request.onupgradeneeded = unexpectedSuccessHandler;
+ request.onsuccess = grabEventAndContinueHandler;
+ let event = yield undefined;
+
+ is(event.type, "success", "Correct event type");
+
+ request = indexedDB.open(dbName2, 1);
+ request.onerror = errorHandler;
+ request.onupgradeneeded = unexpectedSuccessHandler;
+ request.onsuccess = grabEventAndContinueHandler;
+ event = yield undefined;
+
+ is(event.type, "success", "Got correct event type");
+
+ request = indexedDB.open(dbName3, 1);
+ request.onerror = errorHandler;
+ request.onupgradeneeded = unexpectedSuccessHandler;
+ request.onsuccess = grabEventAndContinueHandler;
+ event = yield undefined;
+
+ is(event.type, "success", "Got correct event type");
+
+ clearAllDatabases(continueToNextStepSync);
+ yield undefined;
+
+ request = indexedDB.open(dbName3, 1);
+ request.onerror = errorHandler;
+ request.onupgradeneeded = grabEventAndContinueHandler;
+ request.onsuccess = unexpectedSuccessHandler;
+ event = yield undefined;
+
+ is(event.type, "upgradeneeded", "Got correct event type");
+
+ request.onupgradeneeded = unexpectedSuccessHandler;
+ request.onsuccess = grabEventAndContinueHandler;
+ event = yield undefined;
+
+ is(event.type, "success", "Got correct event type");
+
+ resetAllDatabases(continueToNextStepSync);
+ yield undefined;
+
+ request = indexedDB.open(dbName3, 1);
+ request.onerror = errorHandler;
+ request.onupgradeneeded = unexpectedSuccessHandler;
+ request.onsuccess = grabEventAndContinueHandler;
+ event = yield undefined;
+
+ is(event.type, "success", "Got correct event type");
+
+ finishTest();
+ yield undefined;
+}
+
+function installPackagedProfile(packageName)
+{
+ let directoryService = Cc["@mozilla.org/file/directory_service;1"]
+ .getService(Ci.nsIProperties);
+
+ let profileDir = directoryService.get("ProfD", Ci.nsIFile);
+
+ let currentDir = directoryService.get("CurWorkD", Ci.nsIFile);
+
+ let packageFile = currentDir.clone();
+ packageFile.append(packageName + ".zip");
+
+ let zipReader = Cc["@mozilla.org/libjar/zip-reader;1"]
+ .createInstance(Ci.nsIZipReader);
+ zipReader.open(packageFile);
+
+ let entryNames = [];
+ let entries = zipReader.findEntries(null);
+ while (entries.hasMore()) {
+ let entry = entries.getNext();
+ if (entry != "create_db.html") {
+ entryNames.push(entry);
+ }
+ }
+ entryNames.sort();
+
+ for (let entryName of entryNames) {
+ let zipentry = zipReader.getEntry(entryName);
+
+ let file = profileDir.clone();
+ let split = entryName.split("/");
+ for(let i = 0; i < split.length; i++) {
+ file.append(split[i]);
+ }
+
+ if (zipentry.isDirectory) {
+ file.create(Ci.nsIFile.DIRECTORY_TYPE, parseInt("0755", 8));
+ } else {
+ let istream = zipReader.getInputStream(entryName);
+
+ var ostream = Cc["@mozilla.org/network/file-output-stream;1"]
+ .createInstance(Ci.nsIFileOutputStream);
+ ostream.init(file, -1, parseInt("0644", 8), 0);
+
+ let bostream = Cc['@mozilla.org/network/buffered-output-stream;1']
+ .createInstance(Ci.nsIBufferedOutputStream);
+ bostream.init(ostream, 32768);
+
+ bostream.writeFrom(istream, istream.available());
+
+ istream.close();
+ bostream.close();
+ }
+ }
+
+ zipReader.close();
+}
--- a/dom/indexedDB/test/unit/xpcshell-head-parent-process.js
+++ b/dom/indexedDB/test/unit/xpcshell-head-parent-process.js
@@ -225,17 +225,17 @@ function setTimeout(fun, timeout) {
fun();
}
};
timer.initWithCallback(event, timeout,
Components.interfaces.nsITimer.TYPE_ONE_SHOT);
return timer;
}
-function clearAllDatabases(callback) {
+function resetOrClearAllDatabases(callback, clear) {
if (!SpecialPowers.isMainProcess()) {
throw new Error("clearAllDatabases not implemented for child processes!");
}
let quotaManager = Cc["@mozilla.org/dom/quota/manager;1"]
.getService(Ci.nsIQuotaManager);
const quotaPref = "dom.quotaManager.testing";
@@ -243,17 +243,21 @@ function clearAllDatabases(callback) {
let oldPrefValue;
if (SpecialPowers._getPrefs().prefHasUserValue(quotaPref)) {
oldPrefValue = SpecialPowers.getBoolPref(quotaPref);
}
SpecialPowers.setBoolPref(quotaPref, true);
try {
- quotaManager.clear();
+ if (clear) {
+ quotaManager.clear();
+ } else {
+ quotaManager.reset();
+ }
} catch(e) {
if (oldPrefValue !== undefined) {
SpecialPowers.setBoolPref(quotaPref, oldPrefValue);
} else {
SpecialPowers.clearUserPref(quotaPref);
}
throw e;
}
@@ -261,16 +265,24 @@ function clearAllDatabases(callback) {
let uri = Cc["@mozilla.org/network/io-service;1"]
.getService(Ci.nsIIOService)
.newURI("http://foo.com", null, null);
quotaManager.getUsageForURI(uri, function(usage, fileUsage) {
callback();
});
}
+function resetAllDatabases(callback) {
+ resetOrClearAllDatabases(callback, false);
+}
+
+function clearAllDatabases(callback) {
+ resetOrClearAllDatabases(callback, true);
+}
+
var SpecialPowers = {
isMainProcess: function() {
return Components.classes["@mozilla.org/xre/app-info;1"]
.getService(Components.interfaces.nsIXULRuntime)
.processType == Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT;
},
notifyObservers: function(subject, topic, data) {
var obsvc = Cc['@mozilla.org/observer-service;1']
--- a/dom/indexedDB/test/unit/xpcshell-parent-process.ini
+++ b/dom/indexedDB/test/unit/xpcshell-parent-process.ini
@@ -3,25 +3,27 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
[DEFAULT]
dupe-manifest =
head = xpcshell-head-parent-process.js
tail =
skip-if = toolkit == 'android' || toolkit == 'gonk'
support-files =
+ bug1056939.zip
GlobalObjectsChild.js
GlobalObjectsComponent.js
GlobalObjectsComponent.manifest
GlobalObjectsModule.jsm
GlobalObjectsSandbox.js
xpcshell-shared.ini
[include:xpcshell-shared.ini]
+[test_bug1056939.js]
[test_globalObjects_ipc.js]
[test_invalidate.js]
# disabled for the moment.
skip-if = true
[test_lowDiskSpace.js]
[test_temporary_storage.js]
# bug 951017: intermittent failure on Android x86 emulator
skip-if = os == "android" && processor == "x86"
--- a/dom/quota/QuotaManager.cpp
+++ b/dom/quota/QuotaManager.cpp
@@ -377,18 +377,17 @@ public:
}
}
static void
InvalidateOpenedStorages(nsTArray<nsCOMPtr<nsIOfflineStorage> >& aStorages,
void* aClosure);
void
- DeleteFiles(QuotaManager* aQuotaManager,
- PersistenceType aPersistenceType);
+ DeleteFiles(QuotaManager* aQuotaManager);
private:
~ResetOrClearRunnable() {}
CallbackState mCallbackState;
bool mClear;
};
@@ -988,16 +987,19 @@ QuotaManager::Init()
NS_ENSURE_SUCCESS(rv, rv);
rv = indexedDBDir->GetPath(mIndexedDBPath);
NS_ENSURE_SUCCESS(rv, rv);
rv = baseDir->Append(NS_LITERAL_STRING("storage"));
NS_ENSURE_SUCCESS(rv, rv);
+ rv = baseDir->GetPath(mStoragePath);
+ NS_ENSURE_SUCCESS(rv, rv);
+
nsCOMPtr<nsIFile> persistentStorageDir;
rv = baseDir->Clone(getter_AddRefs(persistentStorageDir));
NS_ENSURE_SUCCESS(rv, rv);
rv = persistentStorageDir->Append(NS_LITERAL_STRING("persistent"));
NS_ENSURE_SUCCESS(rv, rv);
rv = persistentStorageDir->GetPath(mPersistentStoragePath);
@@ -1972,16 +1974,17 @@ QuotaManager::OriginClearCompleted(
void
QuotaManager::ResetOrClearCompleted()
{
AssertIsOnIOThread();
mInitializedOrigins.Clear();
mTemporaryStorageInitialized = false;
+ mStorageAreaInitialized = false;
ReleaseIOThreadObjects();
}
already_AddRefed<mozilla::dom::quota::Client>
QuotaManager::GetClient(Client::Type aClientType)
{
nsRefPtr<Client> client = mClients.SafeElementAt(aClientType);
@@ -3923,29 +3926,28 @@ ResetOrClearRunnable::InvalidateOpenedSt
storages.SwapElements(aStorages);
for (uint32_t index = 0; index < storages.Length(); index++) {
storages[index]->Invalidate();
}
}
void
-ResetOrClearRunnable::DeleteFiles(QuotaManager* aQuotaManager,
- PersistenceType aPersistenceType)
+ResetOrClearRunnable::DeleteFiles(QuotaManager* aQuotaManager)
{
AssertIsOnIOThread();
NS_ASSERTION(aQuotaManager, "Don't pass me null!");
nsresult rv;
nsCOMPtr<nsIFile> directory =
do_CreateInstance(NS_LOCAL_FILE_CONTRACTID, &rv);
NS_ENSURE_SUCCESS_VOID(rv);
- rv = directory->InitWithPath(aQuotaManager->GetStoragePath(aPersistenceType));
+ rv = directory->InitWithPath(aQuotaManager->GetStoragePath());
NS_ENSURE_SUCCESS_VOID(rv);
rv = directory->Remove(true);
if (rv != NS_ERROR_FILE_TARGET_DOES_NOT_EXIST &&
rv != NS_ERROR_FILE_NOT_FOUND && NS_FAILED(rv)) {
// This should never fail if we've closed all storage connections
// correctly...
NS_ERROR("Failed to remove directory!");
@@ -3983,18 +3985,17 @@ ResetOrClearRunnable::Run()
}
case IO: {
AssertIsOnIOThread();
AdvanceState();
if (mClear) {
- DeleteFiles(quotaManager, PERSISTENCE_TYPE_PERSISTENT);
- DeleteFiles(quotaManager, PERSISTENCE_TYPE_TEMPORARY);
+ DeleteFiles(quotaManager);
}
quotaManager->RemoveQuota();
quotaManager->ResetOrClearCompleted();
// Now dispatch back to the main thread.
if (NS_FAILED(NS_DispatchToMainThread(this, NS_DISPATCH_NORMAL))) {
NS_WARNING("Failed to dispatch to main thread!");
--- a/dom/quota/QuotaManager.h
+++ b/dom/quota/QuotaManager.h
@@ -275,16 +275,22 @@ public:
NS_ASSERTION(mIOThread, "This should never be null!");
return mIOThread;
}
already_AddRefed<Client>
GetClient(Client::Type aClientType);
const nsString&
+ GetStoragePath() const
+ {
+ return mStoragePath;
+ }
+
+ const nsString&
GetStoragePath(PersistenceType aPersistenceType) const
{
if (aPersistenceType == PERSISTENCE_TYPE_PERSISTENT) {
return mPersistentStoragePath;
}
NS_ASSERTION(aPersistenceType == PERSISTENCE_TYPE_TEMPORARY, "Huh?");
@@ -515,16 +521,17 @@ private:
// A list of all successfully initialized origins. This list isn't protected
// by any mutex but it is only ever touched on the IO thread.
nsTArray<nsCString> mInitializedOrigins;
nsAutoTArray<nsRefPtr<Client>, Client::TYPE_MAX> mClients;
nsString mIndexedDBPath;
+ nsString mStoragePath;
nsString mPersistentStoragePath;
nsString mTemporaryStoragePath;
uint64_t mTemporaryStorageLimit;
uint64_t mTemporaryStorageUsage;
bool mTemporaryStorageInitialized;
bool mStorageAreaInitialized;