mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1056939 - indexedDB.open fails for certain database names - part 2; r=bent
This commit is contained in:
parent
2276516709
commit
eb5e098231
@ -9156,18 +9156,18 @@ QuotaClient::GetType()
|
|||||||
return QuotaClient::IDB;
|
return QuotaClient::IDB;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
|
||||||
QuotaClient::InitOrigin(PersistenceType aPersistenceType,
|
|
||||||
const nsACString& aGroup,
|
|
||||||
const nsACString& aOrigin,
|
|
||||||
UsageInfo* aUsageInfo)
|
|
||||||
{
|
|
||||||
struct FileManagerInitInfo
|
struct FileManagerInitInfo
|
||||||
{
|
{
|
||||||
nsCOMPtr<nsIFile> mDirectory;
|
nsCOMPtr<nsIFile> mDirectory;
|
||||||
nsCOMPtr<nsIFile> mDatabaseFile;
|
nsCOMPtr<nsIFile> mDatabaseFile;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
QuotaClient::InitOrigin(PersistenceType aPersistenceType,
|
||||||
|
const nsACString& aGroup,
|
||||||
|
const nsACString& aOrigin,
|
||||||
|
UsageInfo* aUsageInfo)
|
||||||
|
{
|
||||||
AssertIsOnIOThread();
|
AssertIsOnIOThread();
|
||||||
|
|
||||||
nsCOMPtr<nsIFile> directory;
|
nsCOMPtr<nsIFile> directory;
|
||||||
@ -9213,13 +9213,6 @@ QuotaClient::InitOrigin(PersistenceType aPersistenceType,
|
|||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (StringEndsWith(leafName, NS_LITERAL_STRING(".sqlite-journal"))) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (leafName.EqualsLiteral(DSSTORE_FILE_NAME)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isDirectory;
|
bool isDirectory;
|
||||||
rv = file->IsDirectory(&isDirectory);
|
rv = file->IsDirectory(&isDirectory);
|
||||||
@ -9235,6 +9228,15 @@ QuotaClient::InitOrigin(PersistenceType aPersistenceType,
|
|||||||
continue;
|
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;
|
nsDependentSubstring dbBaseFilename;
|
||||||
if (!GetDatabaseBaseFilename(leafName, dbBaseFilename)) {
|
if (!GetDatabaseBaseFilename(leafName, dbBaseFilename)) {
|
||||||
unknownFiles.AppendElement(file);
|
unknownFiles.AppendElement(file);
|
||||||
@ -9282,16 +9284,14 @@ QuotaClient::InitOrigin(PersistenceType aPersistenceType,
|
|||||||
// it. Check to see if we have a database that references this directory.
|
// it. Check to see if we have a database that references this directory.
|
||||||
nsString subdirNameWithSuffix = subdirName + filesSuffix;
|
nsString subdirNameWithSuffix = subdirName + filesSuffix;
|
||||||
if (!validSubdirs.GetEntry(subdirNameWithSuffix)) {
|
if (!validSubdirs.GetEntry(subdirNameWithSuffix)) {
|
||||||
#ifdef XP_WIN
|
|
||||||
// Windows doesn't allow a directory to end with a dot ('.'), so we have
|
// Windows doesn't allow a directory to end with a dot ('.'), so we have
|
||||||
// to check that possibility here too.
|
// 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;
|
subdirNameWithSuffix = subdirName + NS_LITERAL_STRING(".") + filesSuffix;
|
||||||
if (NS_WARN_IF(!validSubdirs.GetEntry(subdirNameWithSuffix))) {
|
if (NS_WARN_IF(!validSubdirs.GetEntry(subdirNameWithSuffix))) {
|
||||||
return NS_ERROR_UNEXPECTED;
|
return NS_ERROR_UNEXPECTED;
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
return NS_ERROR_UNEXPECTED;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// We do have a database that uses this directory so we should rename it
|
// We do have a database that uses this directory so we should rename it
|
||||||
@ -9339,29 +9339,6 @@ QuotaClient::InitOrigin(PersistenceType aPersistenceType,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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++) {
|
for (uint32_t count = initInfos.Length(), i = 0; i < count; i++) {
|
||||||
FileManagerInitInfo& initInfo = initInfos[i];
|
FileManagerInitInfo& initInfo = initInfos[i];
|
||||||
MOZ_ASSERT(initInfo.mDirectory);
|
MOZ_ASSERT(initInfo.mDirectory);
|
||||||
@ -9397,6 +9374,23 @@ QuotaClient::InitOrigin(PersistenceType aPersistenceType,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BIN
dom/indexedDB/test/unit/bug1056939.zip
Normal file
BIN
dom/indexedDB/test/unit/bug1056939.zip
Normal file
Binary file not shown.
131
dom/indexedDB/test/unit/test_bug1056939.js
Normal file
131
dom/indexedDB/test/unit/test_bug1056939.js
Normal file
@ -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();
|
||||||
|
}
|
@ -230,7 +230,7 @@ function setTimeout(fun, timeout) {
|
|||||||
return timer;
|
return timer;
|
||||||
}
|
}
|
||||||
|
|
||||||
function clearAllDatabases(callback) {
|
function resetOrClearAllDatabases(callback, clear) {
|
||||||
if (!SpecialPowers.isMainProcess()) {
|
if (!SpecialPowers.isMainProcess()) {
|
||||||
throw new Error("clearAllDatabases not implemented for child processes!");
|
throw new Error("clearAllDatabases not implemented for child processes!");
|
||||||
}
|
}
|
||||||
@ -248,7 +248,11 @@ function clearAllDatabases(callback) {
|
|||||||
SpecialPowers.setBoolPref(quotaPref, true);
|
SpecialPowers.setBoolPref(quotaPref, true);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
if (clear) {
|
||||||
quotaManager.clear();
|
quotaManager.clear();
|
||||||
|
} else {
|
||||||
|
quotaManager.reset();
|
||||||
|
}
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
if (oldPrefValue !== undefined) {
|
if (oldPrefValue !== undefined) {
|
||||||
SpecialPowers.setBoolPref(quotaPref, oldPrefValue);
|
SpecialPowers.setBoolPref(quotaPref, oldPrefValue);
|
||||||
@ -266,6 +270,14 @@ function clearAllDatabases(callback) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function resetAllDatabases(callback) {
|
||||||
|
resetOrClearAllDatabases(callback, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
function clearAllDatabases(callback) {
|
||||||
|
resetOrClearAllDatabases(callback, true);
|
||||||
|
}
|
||||||
|
|
||||||
var SpecialPowers = {
|
var SpecialPowers = {
|
||||||
isMainProcess: function() {
|
isMainProcess: function() {
|
||||||
return Components.classes["@mozilla.org/xre/app-info;1"]
|
return Components.classes["@mozilla.org/xre/app-info;1"]
|
||||||
|
@ -8,6 +8,7 @@ head = xpcshell-head-parent-process.js
|
|||||||
tail =
|
tail =
|
||||||
skip-if = toolkit == 'android' || toolkit == 'gonk'
|
skip-if = toolkit == 'android' || toolkit == 'gonk'
|
||||||
support-files =
|
support-files =
|
||||||
|
bug1056939.zip
|
||||||
GlobalObjectsChild.js
|
GlobalObjectsChild.js
|
||||||
GlobalObjectsComponent.js
|
GlobalObjectsComponent.js
|
||||||
GlobalObjectsComponent.manifest
|
GlobalObjectsComponent.manifest
|
||||||
@ -17,6 +18,7 @@ support-files =
|
|||||||
|
|
||||||
[include:xpcshell-shared.ini]
|
[include:xpcshell-shared.ini]
|
||||||
|
|
||||||
|
[test_bug1056939.js]
|
||||||
[test_globalObjects_ipc.js]
|
[test_globalObjects_ipc.js]
|
||||||
[test_invalidate.js]
|
[test_invalidate.js]
|
||||||
# disabled for the moment.
|
# disabled for the moment.
|
||||||
|
@ -382,8 +382,7 @@ public:
|
|||||||
void* aClosure);
|
void* aClosure);
|
||||||
|
|
||||||
void
|
void
|
||||||
DeleteFiles(QuotaManager* aQuotaManager,
|
DeleteFiles(QuotaManager* aQuotaManager);
|
||||||
PersistenceType aPersistenceType);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
~ResetOrClearRunnable() {}
|
~ResetOrClearRunnable() {}
|
||||||
@ -993,6 +992,9 @@ QuotaManager::Init()
|
|||||||
rv = baseDir->Append(NS_LITERAL_STRING("storage"));
|
rv = baseDir->Append(NS_LITERAL_STRING("storage"));
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
rv = baseDir->GetPath(mStoragePath);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
nsCOMPtr<nsIFile> persistentStorageDir;
|
nsCOMPtr<nsIFile> persistentStorageDir;
|
||||||
rv = baseDir->Clone(getter_AddRefs(persistentStorageDir));
|
rv = baseDir->Clone(getter_AddRefs(persistentStorageDir));
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
@ -1977,6 +1979,7 @@ QuotaManager::ResetOrClearCompleted()
|
|||||||
|
|
||||||
mInitializedOrigins.Clear();
|
mInitializedOrigins.Clear();
|
||||||
mTemporaryStorageInitialized = false;
|
mTemporaryStorageInitialized = false;
|
||||||
|
mStorageAreaInitialized = false;
|
||||||
|
|
||||||
ReleaseIOThreadObjects();
|
ReleaseIOThreadObjects();
|
||||||
}
|
}
|
||||||
@ -3928,8 +3931,7 @@ ResetOrClearRunnable::InvalidateOpenedStorages(
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ResetOrClearRunnable::DeleteFiles(QuotaManager* aQuotaManager,
|
ResetOrClearRunnable::DeleteFiles(QuotaManager* aQuotaManager)
|
||||||
PersistenceType aPersistenceType)
|
|
||||||
{
|
{
|
||||||
AssertIsOnIOThread();
|
AssertIsOnIOThread();
|
||||||
NS_ASSERTION(aQuotaManager, "Don't pass me null!");
|
NS_ASSERTION(aQuotaManager, "Don't pass me null!");
|
||||||
@ -3940,7 +3942,7 @@ ResetOrClearRunnable::DeleteFiles(QuotaManager* aQuotaManager,
|
|||||||
do_CreateInstance(NS_LOCAL_FILE_CONTRACTID, &rv);
|
do_CreateInstance(NS_LOCAL_FILE_CONTRACTID, &rv);
|
||||||
NS_ENSURE_SUCCESS_VOID(rv);
|
NS_ENSURE_SUCCESS_VOID(rv);
|
||||||
|
|
||||||
rv = directory->InitWithPath(aQuotaManager->GetStoragePath(aPersistenceType));
|
rv = directory->InitWithPath(aQuotaManager->GetStoragePath());
|
||||||
NS_ENSURE_SUCCESS_VOID(rv);
|
NS_ENSURE_SUCCESS_VOID(rv);
|
||||||
|
|
||||||
rv = directory->Remove(true);
|
rv = directory->Remove(true);
|
||||||
@ -3988,8 +3990,7 @@ ResetOrClearRunnable::Run()
|
|||||||
AdvanceState();
|
AdvanceState();
|
||||||
|
|
||||||
if (mClear) {
|
if (mClear) {
|
||||||
DeleteFiles(quotaManager, PERSISTENCE_TYPE_PERSISTENT);
|
DeleteFiles(quotaManager);
|
||||||
DeleteFiles(quotaManager, PERSISTENCE_TYPE_TEMPORARY);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
quotaManager->RemoveQuota();
|
quotaManager->RemoveQuota();
|
||||||
|
@ -279,6 +279,12 @@ public:
|
|||||||
already_AddRefed<Client>
|
already_AddRefed<Client>
|
||||||
GetClient(Client::Type aClientType);
|
GetClient(Client::Type aClientType);
|
||||||
|
|
||||||
|
const nsString&
|
||||||
|
GetStoragePath() const
|
||||||
|
{
|
||||||
|
return mStoragePath;
|
||||||
|
}
|
||||||
|
|
||||||
const nsString&
|
const nsString&
|
||||||
GetStoragePath(PersistenceType aPersistenceType) const
|
GetStoragePath(PersistenceType aPersistenceType) const
|
||||||
{
|
{
|
||||||
@ -520,6 +526,7 @@ private:
|
|||||||
nsAutoTArray<nsRefPtr<Client>, Client::TYPE_MAX> mClients;
|
nsAutoTArray<nsRefPtr<Client>, Client::TYPE_MAX> mClients;
|
||||||
|
|
||||||
nsString mIndexedDBPath;
|
nsString mIndexedDBPath;
|
||||||
|
nsString mStoragePath;
|
||||||
nsString mPersistentStoragePath;
|
nsString mPersistentStoragePath;
|
||||||
nsString mTemporaryStoragePath;
|
nsString mTemporaryStoragePath;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user