summaryrefslogtreecommitdiffstats
path: root/dom/indexedDB/ActorsParent.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'dom/indexedDB/ActorsParent.cpp')
-rw-r--r--dom/indexedDB/ActorsParent.cpp108
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;"
));