diff options
Diffstat (limited to 'dom/indexedDB/ActorsParent.cpp')
-rw-r--r-- | dom/indexedDB/ActorsParent.cpp | 108 |
1 files changed, 85 insertions, 23 deletions
diff --git a/dom/indexedDB/ActorsParent.cpp b/dom/indexedDB/ActorsParent.cpp index 702d5c985..9d4e72f2f 100644 --- a/dom/indexedDB/ActorsParent.cpp +++ b/dom/indexedDB/ActorsParent.cpp @@ -7,6 +7,7 @@ #include "ActorsParent.h" #include <algorithm> +#include <stdint.h> // UINTPTR_MAX, uintptr_t #include "FileInfo.h" #include "FileManager.h" #include "IDBObjectStore.h" @@ -859,6 +860,11 @@ ReadCompressedIndexDataValuesFromBlob(const uint8_t* aBlobData, "ReadCompressedIndexDataValuesFromBlob", js::ProfileEntry::Category::STORAGE); + if (uintptr_t(aBlobData) > UINTPTR_MAX - aBlobDataLength) { + IDB_REPORT_INTERNAL_ERR(); + return NS_ERROR_FILE_CORRUPTED; + } + const uint8_t* blobDataIter = aBlobData; const uint8_t* blobDataEnd = aBlobData + aBlobDataLength; @@ -878,7 +884,8 @@ ReadCompressedIndexDataValuesFromBlob(const uint8_t* aBlobData, if (NS_WARN_IF(blobDataIter == blobDataEnd) || NS_WARN_IF(keyBufferLength > uint64_t(UINT32_MAX)) || - NS_WARN_IF(blobDataIter + keyBufferLength > blobDataEnd)) { + NS_WARN_IF(keyBufferLength > uintptr_t(blobDataEnd)) || + NS_WARN_IF(blobDataIter > blobDataEnd - keyBufferLength)) { IDB_REPORT_INTERNAL_ERR(); return NS_ERROR_FILE_CORRUPTED; } @@ -896,7 +903,8 @@ ReadCompressedIndexDataValuesFromBlob(const uint8_t* aBlobData, if (sortKeyBufferLength > 0) { if (NS_WARN_IF(blobDataIter == blobDataEnd) || NS_WARN_IF(sortKeyBufferLength > uint64_t(UINT32_MAX)) || - NS_WARN_IF(blobDataIter + sortKeyBufferLength > blobDataEnd)) { + NS_WARN_IF(sortKeyBufferLength > uintptr_t(blobDataEnd)) || + NS_WARN_IF(blobDataIter > blobDataEnd - sortKeyBufferLength)) { IDB_REPORT_INTERNAL_ERR(); return NS_ERROR_FILE_CORRUPTED; } @@ -18177,11 +18185,25 @@ QuotaClient::ShutdownWorkThreads() mShutdownRequested = true; + // Shutdown maintenance thread pool (this spins the event loop until all + // threads are gone). This should release any maintenance related quota + // objects. if (mMaintenanceThreadPool) { mMaintenanceThreadPool->Shutdown(); mMaintenanceThreadPool = nullptr; } + // Let any runnables dispatched from dying maintenance threads to be + // processed. This should release any maintenance related directory locks. + if (mCurrentMaintenance) { + nsIThread* currentThread = NS_GetCurrentThread(); + MOZ_ASSERT(currentThread); + + do { + MOZ_ALWAYS_TRUE(NS_ProcessNextEvent(currentThread)); + } while (!mCurrentMaintenance); + } + RefPtr<ConnectionPool> connectionPool = gConnectionPool.get(); if (connectionPool) { connectionPool->Shutdown(); @@ -18401,7 +18423,8 @@ Maintenance::Start() AssertIsOnBackgroundThread(); MOZ_ASSERT(mState == State::Initial); - if (IsAborted()) { + if (NS_WARN_IF(QuotaClient::IsShuttingDownOnBackgroundThread()) || + IsAborted()) { return NS_ERROR_ABORT; } @@ -18425,7 +18448,8 @@ Maintenance::CreateIndexedDatabaseManager() MOZ_ASSERT(NS_IsMainThread()); MOZ_ASSERT(mState == State::CreateIndexedDatabaseManager); - if (IsAborted()) { + if (NS_WARN_IF(QuotaClient::IsShuttingDownOnNonBackgroundThread()) || + IsAborted()) { return NS_ERROR_ABORT; } @@ -18450,7 +18474,8 @@ Maintenance::OpenDirectory() MOZ_ASSERT(!mDirectoryLock); MOZ_ASSERT(QuotaManager::Get()); - if (IsAborted()) { + if (NS_WARN_IF(QuotaClient::IsShuttingDownOnBackgroundThread()) || + IsAborted()) { return NS_ERROR_ABORT; } @@ -18474,7 +18499,8 @@ Maintenance::DirectoryOpen() MOZ_ASSERT(mState == State::DirectoryOpenPending); MOZ_ASSERT(mDirectoryLock); - if (IsAborted()) { + if (NS_WARN_IF(QuotaClient::IsShuttingDownOnBackgroundThread()) || + IsAborted()) { return NS_ERROR_ABORT; } @@ -18504,7 +18530,8 @@ Maintenance::DirectoryWork() // We have to find all database files that match any persistence type and any // origin. We ignore anything out of the ordinary for now. - if (IsAborted()) { + if (NS_WARN_IF(QuotaClient::IsShuttingDownOnNonBackgroundThread()) || + IsAborted()) { return NS_ERROR_ABORT; } @@ -18691,8 +18718,10 @@ Maintenance::DirectoryWork() continue; } + nsCString suffix; nsCString group; nsCString origin; + bool isApp; nsTArray<nsString> databasePaths; while (true) { @@ -18748,19 +18777,18 @@ Maintenance::DirectoryWork() // Found a database. if (databasePaths.IsEmpty()) { + MOZ_ASSERT(suffix.IsEmpty()); MOZ_ASSERT(group.IsEmpty()); MOZ_ASSERT(origin.IsEmpty()); int64_t dummyTimeStamp; - nsCString dummySuffix; - bool dummyIsApp; if (NS_WARN_IF(NS_FAILED( quotaManager->GetDirectoryMetadata2(originDir, &dummyTimeStamp, - dummySuffix, + suffix, group, origin, - &dummyIsApp)))) { + &isApp)))) { // Not much we can do here... continue; } @@ -18776,6 +18804,22 @@ Maintenance::DirectoryWork() group, origin, Move(databasePaths))); + + nsCOMPtr<nsIFile> directory; + + // Idle maintenance may occur before origin is initailized. + // Ensure origin is initialized first. It will initialize all origins + // for temporary storage including IDB origins. + rv = quotaManager->EnsureOriginIsInitialized(persistenceType, + suffix, + group, + origin, + isApp, + getter_AddRefs(directory)); + + if (NS_WARN_IF(NS_FAILED(rv))) { + return rv; + } } } } @@ -18827,6 +18871,11 @@ Maintenance::BeginDatabaseMaintenance() } }; + if (NS_WARN_IF(QuotaClient::IsShuttingDownOnBackgroundThread()) || + IsAborted()) { + return NS_ERROR_ABORT; + } + RefPtr<nsThreadPool> threadPool; for (DirectoryInfo& directoryInfo : mDirectoryInfos) { @@ -19013,6 +19062,11 @@ DatabaseMaintenance::PerformMaintenanceOnDatabase() } }; + if (NS_WARN_IF(QuotaClient::IsShuttingDownOnNonBackgroundThread()) || + mMaintenance->IsAborted()) { + return; + } + nsCOMPtr<nsIFile> databaseFile = GetFileForPath(mDatabasePath); MOZ_ASSERT(databaseFile); @@ -19029,10 +19083,6 @@ DatabaseMaintenance::PerformMaintenanceOnDatabase() AutoClose autoClose(connection); - if (mMaintenance->IsAborted()) { - return; - } - AutoProgressHandler progressHandler(mMaintenance); if (NS_WARN_IF(NS_FAILED(progressHandler.Register(connection)))) { return; @@ -19051,20 +19101,12 @@ DatabaseMaintenance::PerformMaintenanceOnDatabase() return; } - if (mMaintenance->IsAborted()) { - return; - } - MaintenanceAction maintenanceAction; rv = DetermineMaintenanceAction(connection, databaseFile, &maintenanceAction); if (NS_WARN_IF(NS_FAILED(rv))) { return; } - if (mMaintenance->IsAborted()) { - return; - } - switch (maintenanceAction) { case MaintenanceAction::Nothing: break; @@ -19091,6 +19133,11 @@ DatabaseMaintenance::CheckIntegrity(mozIStorageConnection* aConnection, MOZ_ASSERT(aConnection); MOZ_ASSERT(aOk); + if (NS_WARN_IF(QuotaClient::IsShuttingDownOnNonBackgroundThread()) || + mMaintenance->IsAborted()) { + return NS_ERROR_ABORT; + } + nsresult rv; // First do a full integrity_check. Scope statements tightly here because @@ -19208,6 +19255,11 @@ DatabaseMaintenance::DetermineMaintenanceAction( MOZ_ASSERT(aDatabaseFile); MOZ_ASSERT(aMaintenanceAction); + if (NS_WARN_IF(QuotaClient::IsShuttingDownOnNonBackgroundThread()) || + mMaintenance->IsAborted()) { + return NS_ERROR_ABORT; + } + int32_t schemaVersion; nsresult rv = aConnection->GetSchemaVersion(&schemaVersion); if (NS_WARN_IF(NS_FAILED(rv))) { @@ -19417,6 +19469,11 @@ DatabaseMaintenance::IncrementalVacuum(mozIStorageConnection* aConnection) MOZ_ASSERT(!IsOnBackgroundThread()); MOZ_ASSERT(aConnection); + if (NS_WARN_IF(QuotaClient::IsShuttingDownOnNonBackgroundThread()) || + mMaintenance->IsAborted()) { + return; + } + nsresult rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING( "PRAGMA incremental_vacuum;" )); @@ -19434,6 +19491,11 @@ DatabaseMaintenance::FullVacuum(mozIStorageConnection* aConnection, MOZ_ASSERT(aConnection); MOZ_ASSERT(aDatabaseFile); + if (NS_WARN_IF(QuotaClient::IsShuttingDownOnNonBackgroundThread()) || + mMaintenance->IsAborted()) { + return; + } + nsresult rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING( "VACUUM;" )); |