summaryrefslogtreecommitdiffstats
path: root/dom/indexedDB
diff options
context:
space:
mode:
Diffstat (limited to 'dom/indexedDB')
-rw-r--r--dom/indexedDB/ActorsParent.cpp56
-rw-r--r--dom/indexedDB/IDBCursor.cpp8
-rw-r--r--dom/indexedDB/IDBDatabase.cpp3
-rw-r--r--dom/indexedDB/IDBFactory.cpp4
-rw-r--r--dom/indexedDB/IDBKeyRange.cpp2
-rw-r--r--dom/indexedDB/IDBObjectStore.cpp36
-rw-r--r--dom/indexedDB/IndexedDatabaseManager.cpp75
-rw-r--r--dom/indexedDB/IndexedDatabaseManager.h17
-rw-r--r--dom/indexedDB/Key.cpp38
-rw-r--r--dom/indexedDB/Key.h15
-rw-r--r--dom/indexedDB/KeyPath.cpp22
-rw-r--r--dom/indexedDB/KeyPath.h12
-rw-r--r--dom/indexedDB/crashtests/1558522-1.html40
-rw-r--r--dom/indexedDB/crashtests/crashtests.list1
-rw-r--r--dom/indexedDB/test/helpers.js4
-rw-r--r--dom/indexedDB/test/mochitest.ini2
-rw-r--r--dom/indexedDB/test/test_lowDiskSpace.html19
-rw-r--r--dom/indexedDB/test/unit/test_lowDiskSpace.js754
-rw-r--r--dom/indexedDB/test/unit/xpcshell-head-parent-process.js3
-rw-r--r--dom/indexedDB/test/unit/xpcshell-parent-process.ini1
20 files changed, 142 insertions, 970 deletions
diff --git a/dom/indexedDB/ActorsParent.cpp b/dom/indexedDB/ActorsParent.cpp
index cd998c31c..74afef452 100644
--- a/dom/indexedDB/ActorsParent.cpp
+++ b/dom/indexedDB/ActorsParent.cpp
@@ -4427,18 +4427,6 @@ CreateStorageConnection(nsIFile* aDBFile,
nsresult rv;
bool exists;
- if (IndexedDatabaseManager::InLowDiskSpaceMode()) {
- rv = aDBFile->Exists(&exists);
- if (NS_WARN_IF(NS_FAILED(rv))) {
- return rv;
- }
-
- if (!exists) {
- NS_WARNING("Refusing to create database because disk space is low!");
- return NS_ERROR_DOM_INDEXEDDB_QUOTA_ERR;
- }
- }
-
nsCOMPtr<nsIFileURL> dbFileUrl;
rv = GetDatabaseFileURL(aDBFile,
aPersistenceType,
@@ -19103,23 +19091,6 @@ DatabaseMaintenance::DetermineMaintenanceAction(
return NS_OK;
}
- bool lowDiskSpace = IndexedDatabaseManager::InLowDiskSpaceMode();
-
- if (QuotaManager::IsRunningXPCShellTests()) {
- // If we're running XPCShell then we want to test both the low disk space
- // and normal disk space code paths so pick semi-randomly based on the
- // current time.
- lowDiskSpace = ((PR_Now() / PR_USEC_PER_MSEC) % 2) == 0;
- }
-
- // If we're low on disk space then the best we can hope for is that an
- // incremental vacuum might free some space. That is a journaled operation so
- // it may not be possible even then.
- if (lowDiskSpace) {
- *aMaintenanceAction = MaintenanceAction::IncrementalVacuum;
- return NS_OK;
- }
-
// This method shouldn't make any permanent changes to the database, so make
// sure everything gets rolled back when we leave.
mozStorageTransaction transaction(aConnection,
@@ -24233,11 +24204,6 @@ CreateFileOp::DoDatabaseWork()
"CreateFileOp::DoDatabaseWork",
js::ProfileEntry::Category::STORAGE);
- if (NS_WARN_IF(IndexedDatabaseManager::InLowDiskSpaceMode())) {
- NS_WARNING("Refusing to create file because disk space is low!");
- return NS_ERROR_DOM_INDEXEDDB_QUOTA_ERR;
- }
-
if (NS_WARN_IF(QuotaManager::IsShuttingDown()) || !OperationMayProceed()) {
IDB_REPORT_INTERNAL_ERR();
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
@@ -24378,10 +24344,6 @@ CreateObjectStoreOp::DoDatabaseWork(DatabaseConnection* aConnection)
"CreateObjectStoreOp::DoDatabaseWork",
js::ProfileEntry::Category::STORAGE);
- if (NS_WARN_IF(IndexedDatabaseManager::InLowDiskSpaceMode())) {
- return NS_ERROR_DOM_INDEXEDDB_QUOTA_ERR;
- }
-
#ifdef DEBUG
{
// Make sure that we're not creating an object store with the same name as
@@ -24705,10 +24667,6 @@ RenameObjectStoreOp::DoDatabaseWork(DatabaseConnection* aConnection)
"RenameObjectStoreOp::DoDatabaseWork",
js::ProfileEntry::Category::STORAGE);
- if (NS_WARN_IF(IndexedDatabaseManager::InLowDiskSpaceMode())) {
- return NS_ERROR_DOM_INDEXEDDB_QUOTA_ERR;
- }
-
#ifdef DEBUG
{
// Make sure that we're not renaming an object store with the same name as
@@ -24798,7 +24756,6 @@ CreateIndexOp::InsertDataFromObjectStore(DatabaseConnection* aConnection)
{
MOZ_ASSERT(aConnection);
aConnection->AssertIsOnConnectionThread();
- MOZ_ASSERT(!IndexedDatabaseManager::InLowDiskSpaceMode());
MOZ_ASSERT(mMaybeUniqueIndexTable);
PROFILER_LABEL("IndexedDB",
@@ -24849,7 +24806,6 @@ CreateIndexOp::InsertDataFromObjectStoreInternal(
{
MOZ_ASSERT(aConnection);
aConnection->AssertIsOnConnectionThread();
- MOZ_ASSERT(!IndexedDatabaseManager::InLowDiskSpaceMode());
MOZ_ASSERT(mMaybeUniqueIndexTable);
DebugOnly<void*> storageConnection = aConnection->GetStorageConnection();
@@ -24926,10 +24882,6 @@ CreateIndexOp::DoDatabaseWork(DatabaseConnection* aConnection)
"CreateIndexOp::DoDatabaseWork",
js::ProfileEntry::Category::STORAGE);
- if (NS_WARN_IF(IndexedDatabaseManager::InLowDiskSpaceMode())) {
- return NS_ERROR_DOM_INDEXEDDB_QUOTA_ERR;
- }
-
#ifdef DEBUG
{
// Make sure that we're not creating an index with the same name and object
@@ -25806,10 +25758,6 @@ RenameIndexOp::DoDatabaseWork(DatabaseConnection* aConnection)
"RenameIndexOp::DoDatabaseWork",
js::ProfileEntry::Category::STORAGE);
- if (NS_WARN_IF(IndexedDatabaseManager::InLowDiskSpaceMode())) {
- return NS_ERROR_DOM_INDEXEDDB_QUOTA_ERR;
- }
-
#ifdef DEBUG
{
// Make sure that we're not renaming an index with the same name as another
@@ -26294,10 +26242,6 @@ ObjectStoreAddOrPutRequestOp::DoDatabaseWork(DatabaseConnection* aConnection)
"ObjectStoreAddOrPutRequestOp::DoDatabaseWork",
js::ProfileEntry::Category::STORAGE);
- if (NS_WARN_IF(IndexedDatabaseManager::InLowDiskSpaceMode())) {
- return NS_ERROR_DOM_INDEXEDDB_QUOTA_ERR;
- }
-
DatabaseConnection::AutoSavepoint autoSave;
nsresult rv = autoSave.Start(Transaction());
if (NS_WARN_IF(NS_FAILED(rv))) {
diff --git a/dom/indexedDB/IDBCursor.cpp b/dom/indexedDB/IDBCursor.cpp
index af88742f0..be0295dc7 100644
--- a/dom/indexedDB/IDBCursor.cpp
+++ b/dom/indexedDB/IDBCursor.cpp
@@ -430,7 +430,7 @@ IDBCursor::Continue(JSContext* aCx,
}
Key key;
- aRv = key.SetFromJSVal(aCx, aKey);
+ aRv = key.SetFromJSVal(aCx, aKey, /* aCallGetters */ true);
if (aRv.Failed()) {
return;
}
@@ -536,7 +536,7 @@ IDBCursor::ContinuePrimaryKey(JSContext* aCx,
}
Key key;
- aRv = key.SetFromJSVal(aCx, aKey);
+ aRv = key.SetFromJSVal(aCx, aKey, /* aCallGetters */ true);
if (aRv.Failed()) {
return;
}
@@ -558,7 +558,7 @@ IDBCursor::ContinuePrimaryKey(JSContext* aCx,
}
Key primaryKey;
- aRv = primaryKey.SetFromJSVal(aCx, aPrimaryKey);
+ aRv = primaryKey.SetFromJSVal(aCx, aPrimaryKey, /* aCallGetters */ true);
if (aRv.Failed()) {
return;
}
@@ -718,7 +718,7 @@ IDBCursor::Update(JSContext* aCx, JS::Handle<JS::Value> aValue,
const KeyPath& keyPath = objectStore->GetKeyPath();
Key key;
- aRv = keyPath.ExtractKey(aCx, aValue, key);
+ aRv = keyPath.ExtractKey(aCx, aValue, key, /* aCallGetters */ false);
if (aRv.Failed()) {
return nullptr;
}
diff --git a/dom/indexedDB/IDBDatabase.cpp b/dom/indexedDB/IDBDatabase.cpp
index 5592e7f93..6ef352801 100644
--- a/dom/indexedDB/IDBDatabase.cpp
+++ b/dom/indexedDB/IDBDatabase.cpp
@@ -1257,6 +1257,9 @@ IDBDatabase::LastRelease()
AssertIsOnOwningThread();
CloseInternal();
+
+ // Make sure that file actors created after the database was closed are expired.
+ ExpireFileActors(/* aExpireAll */ true);
if (mBackgroundActor) {
mBackgroundActor->SendDeleteMeInternal();
diff --git a/dom/indexedDB/IDBFactory.cpp b/dom/indexedDB/IDBFactory.cpp
index c1ef6353d..66471fe24 100644
--- a/dom/indexedDB/IDBFactory.cpp
+++ b/dom/indexedDB/IDBFactory.cpp
@@ -482,13 +482,13 @@ IDBFactory::Cmp(JSContext* aCx, JS::Handle<JS::Value> aFirst,
JS::Handle<JS::Value> aSecond, ErrorResult& aRv)
{
Key first, second;
- nsresult rv = first.SetFromJSVal(aCx, aFirst);
+ nsresult rv = first.SetFromJSVal(aCx, aFirst, /* aCallGetters */ true);
if (NS_FAILED(rv)) {
aRv.Throw(rv);
return 0;
}
- rv = second.SetFromJSVal(aCx, aSecond);
+ rv = second.SetFromJSVal(aCx, aSecond, /* aCallGetters */ true);
if (NS_FAILED(rv)) {
aRv.Throw(rv);
return 0;
diff --git a/dom/indexedDB/IDBKeyRange.cpp b/dom/indexedDB/IDBKeyRange.cpp
index e61c80617..168fb4a5a 100644
--- a/dom/indexedDB/IDBKeyRange.cpp
+++ b/dom/indexedDB/IDBKeyRange.cpp
@@ -24,7 +24,7 @@ GetKeyFromJSVal(JSContext* aCx,
JS::Handle<JS::Value> aVal,
Key& aKey)
{
- nsresult rv = aKey.SetFromJSVal(aCx, aVal);
+ nsresult rv = aKey.SetFromJSVal(aCx, aVal, /* aCallGetters */ true);
if (NS_FAILED(rv)) {
MOZ_ASSERT(NS_ERROR_GET_MODULE(rv) == NS_ERROR_MODULE_DOM_INDEXEDDB);
return rv;
diff --git a/dom/indexedDB/IDBObjectStore.cpp b/dom/indexedDB/IDBObjectStore.cpp
index 756792741..cbac30894 100644
--- a/dom/indexedDB/IDBObjectStore.cpp
+++ b/dom/indexedDB/IDBObjectStore.cpp
@@ -1084,7 +1084,7 @@ IDBObjectStore::AppendIndexUpdateInfo(
if (!aMultiEntry) {
Key key;
- rv = aKeyPath.ExtractKey(aCx, aVal, key);
+ rv = aKeyPath.ExtractKey(aCx, aVal, key, /* aCallGetters */ false);
// If an index's keyPath doesn't match an object, we ignore that object.
if (rv == NS_ERROR_DOM_INDEXEDDB_DATA_ERR || key.IsUnset()) {
@@ -1114,7 +1114,7 @@ IDBObjectStore::AppendIndexUpdateInfo(
}
bool isArray;
- if (!JS_IsArrayObject(aCx, val, &isArray)) {
+ if (NS_WARN_IF(!JS_IsArrayObject(aCx, val, &isArray))) {
IDB_REPORT_INTERNAL_ERR();
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
}
@@ -1127,14 +1127,31 @@ IDBObjectStore::AppendIndexUpdateInfo(
}
for (uint32_t arrayIndex = 0; arrayIndex < arrayLength; arrayIndex++) {
- JS::Rooted<JS::Value> arrayItem(aCx);
- if (NS_WARN_IF(!JS_GetElement(aCx, array, arrayIndex, &arrayItem))) {
+ JS::RootedId indexId(aCx);
+ if (NS_WARN_IF(!JS_IndexToId(aCx, arrayIndex, &indexId))) {
+ IDB_REPORT_INTERNAL_ERR();
+ return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
+ }
+
+ bool hasOwnProperty;
+ if (NS_WARN_IF(
+ !JS_HasOwnPropertyById(aCx, array, indexId, &hasOwnProperty))) {
+ IDB_REPORT_INTERNAL_ERR();
+ return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
+ }
+
+ if (!hasOwnProperty) {
+ continue;
+ }
+
+ JS::RootedValue arrayItem(aCx);
+ if (NS_WARN_IF(!JS_GetPropertyById(aCx, array, indexId, &arrayItem))) {
IDB_REPORT_INTERNAL_ERR();
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
}
Key value;
- if (NS_FAILED(value.SetFromJSVal(aCx, arrayItem)) ||
+ if (NS_FAILED(value.SetFromJSVal(aCx, arrayItem, /* aCallGetters */ false)) ||
value.IsUnset()) {
// Not a value we can do anything with, ignore it.
continue;
@@ -1153,7 +1170,7 @@ IDBObjectStore::AppendIndexUpdateInfo(
}
else {
Key value;
- if (NS_FAILED(value.SetFromJSVal(aCx, val)) ||
+ if (NS_FAILED(value.SetFromJSVal(aCx, val, /* aCallGetters */ false)) ||
value.IsUnset()) {
// Not a value we can do anything with, ignore it.
return NS_OK;
@@ -1324,12 +1341,12 @@ IDBObjectStore::GetAddInfo(JSContext* aCx,
if (!HasValidKeyPath()) {
// Out-of-line keys must be passed in.
- rv = aKey.SetFromJSVal(aCx, aKeyVal);
+ rv = aKey.SetFromJSVal(aCx, aKeyVal, /* aCallGetters */ true);
if (NS_FAILED(rv)) {
return rv;
}
} else if (!isAutoIncrement) {
- rv = GetKeyPath().ExtractKey(aCx, aValue, aKey);
+ rv = GetKeyPath().ExtractKey(aCx, aValue, aKey, /* aCallGetters */ false);
if (NS_FAILED(rv)) {
return rv;
}
@@ -1368,7 +1385,8 @@ IDBObjectStore::GetAddInfo(JSContext* aCx,
aValue,
aKey,
&GetAddInfoCallback,
- &data);
+ &data,
+ /* aCallGetters */ false);
} else {
rv = GetAddInfoCallback(aCx, &data);
}
diff --git a/dom/indexedDB/IndexedDatabaseManager.cpp b/dom/indexedDB/IndexedDatabaseManager.cpp
index 62ba51c08..213de5cc9 100644
--- a/dom/indexedDB/IndexedDatabaseManager.cpp
+++ b/dom/indexedDB/IndexedDatabaseManager.cpp
@@ -8,11 +8,9 @@
#include "chrome/common/ipc_channel.h" // for IPC::Channel::kMaximumMessageSize
#include "nsIConsoleService.h"
-#include "nsIDiskSpaceWatcher.h"
#include "nsIDOMWindow.h"
#include "nsIEventTarget.h"
#include "nsIFile.h"
-#include "nsIObserverService.h"
#include "nsIScriptError.h"
#include "nsIScriptGlobalObject.h"
@@ -64,11 +62,6 @@
#define IDB_STR "indexedDB"
-// The two possible values for the data argument when receiving the disk space
-// observer notification.
-#define LOW_DISK_SPACE_DATA_FULL "full"
-#define LOW_DISK_SPACE_DATA_FREE "free"
-
namespace mozilla {
namespace dom {
namespace indexedDB {
@@ -313,8 +306,6 @@ Atomic<IndexedDatabaseManager::LoggingMode>
IndexedDatabaseManager::sLoggingMode(
IndexedDatabaseManager::Logging_Disabled);
-mozilla::Atomic<bool> IndexedDatabaseManager::sLowDiskSpaceMode(false);
-
// static
IndexedDatabaseManager*
IndexedDatabaseManager::GetOrCreate()
@@ -329,24 +320,6 @@ IndexedDatabaseManager::GetOrCreate()
if (!gDBManager) {
sIsMainProcess = XRE_IsParentProcess();
- if (sIsMainProcess && Preferences::GetBool("disk_space_watcher.enabled", false)) {
- // See if we're starting up in low disk space conditions.
- nsCOMPtr<nsIDiskSpaceWatcher> watcher =
- do_GetService(DISKSPACEWATCHER_CONTRACTID);
- if (watcher) {
- bool isDiskFull;
- if (NS_SUCCEEDED(watcher->GetIsDiskFull(&isDiskFull))) {
- sLowDiskSpaceMode = isDiskFull;
- }
- else {
- NS_WARNING("GetIsDiskFull failed!");
- }
- }
- else {
- NS_WARNING("No disk space watcher component available!");
- }
- }
-
RefPtr<IndexedDatabaseManager> instance(new IndexedDatabaseManager());
nsresult rv = instance->Init();
@@ -380,13 +353,6 @@ IndexedDatabaseManager::Init()
// During Init() we can't yet call IsMainProcess(), just check sIsMainProcess
// directly.
if (sIsMainProcess) {
- nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
- NS_ENSURE_STATE(obs);
-
- nsresult rv =
- obs->AddObserver(this, DISKSPACEWATCHER_OBSERVER_TOPIC, false);
- NS_ENSURE_SUCCESS(rv, rv);
-
mDeleteTimer = do_CreateInstance(NS_TIMER_CONTRACTID);
NS_ENSURE_STATE(mDeleteTimer);
@@ -680,16 +646,6 @@ IndexedDatabaseManager::IsMainProcess()
return sIsMainProcess;
}
-//static
-bool
-IndexedDatabaseManager::InLowDiskSpaceMode()
-{
- NS_ASSERTION(gDBManager,
- "InLowDiskSpaceMode() called before indexedDB has been "
- "initialized!");
- return sLowDiskSpaceMode;
-}
-
// static
IndexedDatabaseManager::LoggingMode
IndexedDatabaseManager::GetLoggingMode()
@@ -1087,36 +1043,7 @@ IndexedDatabaseManager::GetLocale()
NS_IMPL_ADDREF(IndexedDatabaseManager)
NS_IMPL_RELEASE_WITH_DESTROY(IndexedDatabaseManager, Destroy())
-NS_IMPL_QUERY_INTERFACE(IndexedDatabaseManager, nsIObserver, nsITimerCallback)
-
-NS_IMETHODIMP
-IndexedDatabaseManager::Observe(nsISupports* aSubject, const char* aTopic,
- const char16_t* aData)
-{
- NS_ASSERTION(IsMainProcess(), "Wrong process!");
- NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
-
- if (!strcmp(aTopic, DISKSPACEWATCHER_OBSERVER_TOPIC)) {
- NS_ASSERTION(aData, "No data?!");
-
- const nsDependentString data(aData);
-
- if (data.EqualsLiteral(LOW_DISK_SPACE_DATA_FULL)) {
- sLowDiskSpaceMode = true;
- }
- else if (data.EqualsLiteral(LOW_DISK_SPACE_DATA_FREE)) {
- sLowDiskSpaceMode = false;
- }
- else {
- NS_NOTREACHED("Unknown data value!");
- }
-
- return NS_OK;
- }
-
- NS_NOTREACHED("Unknown topic!");
- return NS_ERROR_UNEXPECTED;
-}
+NS_IMPL_QUERY_INTERFACE(IndexedDatabaseManager, nsITimerCallback)
NS_IMETHODIMP
IndexedDatabaseManager::Notify(nsITimer* aTimer)
diff --git a/dom/indexedDB/IndexedDatabaseManager.h b/dom/indexedDB/IndexedDatabaseManager.h
index d63c548ec..fb4376426 100644
--- a/dom/indexedDB/IndexedDatabaseManager.h
+++ b/dom/indexedDB/IndexedDatabaseManager.h
@@ -7,8 +7,6 @@
#ifndef mozilla_dom_indexeddatabasemanager_h__
#define mozilla_dom_indexeddatabasemanager_h__
-#include "nsIObserver.h"
-
#include "js/TypeDecls.h"
#include "mozilla/Atomics.h"
#include "mozilla/dom/quota/PersistenceType.h"
@@ -43,8 +41,7 @@ class FileManagerInfo;
} // namespace indexedDB
class IndexedDatabaseManager final
- : public nsIObserver
- , public nsITimerCallback
+ : public nsITimerCallback
{
typedef mozilla::dom::quota::PersistenceType PersistenceType;
typedef mozilla::dom::quota::QuotaManager QuotaManager;
@@ -62,7 +59,6 @@ public:
};
NS_DECL_ISUPPORTS
- NS_DECL_NSIOBSERVER
NS_DECL_NSITIMERCALLBACK
// Returns a non-owning reference.
@@ -87,16 +83,6 @@ public:
#endif
static bool
- InLowDiskSpaceMode()
-#ifdef DEBUG
- ;
-#else
- {
- return !!sLowDiskSpaceMode;
- }
-#endif
-
- static bool
InTestingMode();
static bool
@@ -244,7 +230,6 @@ private:
static bool sFullSynchronousMode;
static LazyLogModule sLoggingModule;
static Atomic<LoggingMode> sLoggingMode;
- static mozilla::Atomic<bool> sLowDiskSpaceMode;
};
} // namespace dom
diff --git a/dom/indexedDB/Key.cpp b/dom/indexedDB/Key.cpp
index 0f693b2c6..575734af2 100644
--- a/dom/indexedDB/Key.cpp
+++ b/dom/indexedDB/Key.cpp
@@ -201,8 +201,11 @@ Key::ToLocaleBasedKey(Key& aTarget, const nsCString& aLocale) const
}
nsresult
-Key::EncodeJSValInternal(JSContext* aCx, JS::Handle<JS::Value> aVal,
- uint8_t aTypeOffset, uint16_t aRecursionDepth)
+Key::EncodeJSValInternal(JSContext* aCx,
+ JS::Handle<JS::Value> aVal,
+ uint8_t aTypeOffset,
+ uint16_t aRecursionDepth,
+ bool aCallGetters)
{
static_assert(eMaxType * kMaxArrayCollapse < 256,
"Unable to encode jsvals.");
@@ -257,13 +260,18 @@ Key::EncodeJSValInternal(JSContext* aCx, JS::Handle<JS::Value> aVal,
for (uint32_t index = 0; index < length; index++) {
JS::Rooted<JS::Value> val(aCx);
- if (!JS_GetElement(aCx, obj, index, &val)) {
+ bool ok = aCallGetters ? JS_GetElement(aCx, obj, index, &val)
+ : JS_GetOwnElement(aCx, obj, index, &val);
+ if (!ok) {
IDB_REPORT_INTERNAL_ERR();
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
}
- nsresult rv = EncodeJSValInternal(aCx, val, aTypeOffset,
- aRecursionDepth + 1);
+ nsresult rv = EncodeJSValInternal(aCx,
+ val,
+ aTypeOffset,
+ aRecursionDepth + 1,
+ aCallGetters);
if (NS_FAILED(rv)) {
return rv;
}
@@ -406,9 +414,10 @@ Key::DecodeJSValInternal(const unsigned char*& aPos, const unsigned char* aEnd,
nsresult
Key::EncodeJSVal(JSContext* aCx,
JS::Handle<JS::Value> aVal,
- uint8_t aTypeOffset)
+ uint8_t aTypeOffset,
+ bool aCallGetters)
{
- return EncodeJSValInternal(aCx, aVal, aTypeOffset, 0);
+ return EncodeJSValInternal(aCx, aVal, aTypeOffset, 0, aCallGetters);
}
void
@@ -741,7 +750,8 @@ Key::SetFromValueArray(mozIStorageValueArray* aValues,
nsresult
Key::SetFromJSVal(JSContext* aCx,
- JS::Handle<JS::Value> aVal)
+ JS::Handle<JS::Value> aVal,
+ bool aCallGetters)
{
mBuffer.Truncate();
@@ -750,7 +760,7 @@ Key::SetFromJSVal(JSContext* aCx,
return NS_OK;
}
- nsresult rv = EncodeJSVal(aCx, aVal, 0);
+ nsresult rv = EncodeJSVal(aCx, aVal, 0, aCallGetters);
if (NS_FAILED(rv)) {
Unset();
return rv;
@@ -793,9 +803,15 @@ Key::ToJSVal(JSContext* aCx,
}
nsresult
-Key::AppendItem(JSContext* aCx, bool aFirstOfArray, JS::Handle<JS::Value> aVal)
+Key::AppendItem(JSContext* aCx,
+ bool aFirstOfArray,
+ JS::Handle<JS::Value> aVal,
+ bool aCallGetters)
{
- nsresult rv = EncodeJSVal(aCx, aVal, aFirstOfArray ? eMaxType : 0);
+ nsresult rv = EncodeJSVal(aCx,
+ aVal,
+ aFirstOfArray ? eMaxType : 0,
+ aCallGetters);
if (NS_FAILED(rv)) {
Unset();
return rv;
diff --git a/dom/indexedDB/Key.h b/dom/indexedDB/Key.h
index 9d70ce6ad..a4fb65b48 100644
--- a/dom/indexedDB/Key.h
+++ b/dom/indexedDB/Key.h
@@ -203,7 +203,7 @@ public:
}
nsresult
- SetFromJSVal(JSContext* aCx, JS::Handle<JS::Value> aVal);
+ SetFromJSVal(JSContext* aCx, JS::Handle<JS::Value> aVal, bool aCallGetters);
nsresult
ToJSVal(JSContext* aCx, JS::MutableHandle<JS::Value> aVal) const;
@@ -212,7 +212,10 @@ public:
ToJSVal(JSContext* aCx, JS::Heap<JS::Value>& aVal) const;
nsresult
- AppendItem(JSContext* aCx, bool aFirstOfArray, JS::Handle<JS::Value> aVal);
+ AppendItem(JSContext* aCx,
+ bool aFirstOfArray,
+ JS::Handle<JS::Value> aVal,
+ bool aCallGetters);
nsresult
ToLocaleBasedKey(Key& aTarget, const nsCString& aLocale) const;
@@ -283,7 +286,10 @@ private:
// Encoding functions. These append the encoded value to the end of mBuffer
nsresult
- EncodeJSVal(JSContext* aCx, JS::Handle<JS::Value> aVal, uint8_t aTypeOffset);
+ EncodeJSVal(JSContext* aCx,
+ JS::Handle<JS::Value> aVal,
+ uint8_t aTypeOffset,
+ bool aCallGetters);
void
EncodeString(const nsAString& aString, uint8_t aTypeOffset);
@@ -331,7 +337,8 @@ private:
EncodeJSValInternal(JSContext* aCx,
JS::Handle<JS::Value> aVal,
uint8_t aTypeOffset,
- uint16_t aRecursionDepth);
+ uint16_t aRecursionDepth,
+ bool aCallGetters);
static nsresult
DecodeJSValInternal(const unsigned char*& aPos,
diff --git a/dom/indexedDB/KeyPath.cpp b/dom/indexedDB/KeyPath.cpp
index 30edd8cd7..0221c9450 100644
--- a/dom/indexedDB/KeyPath.cpp
+++ b/dom/indexedDB/KeyPath.cpp
@@ -372,11 +372,13 @@ KeyPath::AppendStringWithValidation(const nsAString& aString)
}
nsresult
-KeyPath::ExtractKey(JSContext* aCx, const JS::Value& aValue, Key& aKey) const
+KeyPath::ExtractKey(JSContext* aCx,
+ const JS::Value& aValue,
+ Key& aKey,
+ bool aCallGetters) const
{
uint32_t len = mStrings.Length();
JS::Rooted<JS::Value> value(aCx);
-
aKey.Unset();
for (uint32_t i = 0; i < len; ++i) {
@@ -388,7 +390,10 @@ KeyPath::ExtractKey(JSContext* aCx, const JS::Value& aValue, Key& aKey) const
return rv;
}
- if (NS_FAILED(aKey.AppendItem(aCx, IsArray() && i == 0, value))) {
+ if (NS_FAILED(aKey.AppendItem(aCx,
+ IsArray() && i == 0,
+ value,
+ aCallGetters))) {
NS_ASSERTION(aKey.IsUnset(), "Encoding error should unset");
return NS_ERROR_DOM_INDEXEDDB_DATA_ERR;
}
@@ -437,9 +442,12 @@ KeyPath::ExtractKeyAsJSVal(JSContext* aCx, const JS::Value& aValue,
}
nsresult
-KeyPath::ExtractOrCreateKey(JSContext* aCx, const JS::Value& aValue,
- Key& aKey, ExtractOrCreateKeyCallback aCallback,
- void* aClosure) const
+KeyPath::ExtractOrCreateKey(JSContext* aCx,
+ const JS::Value& aValue,
+ Key& aKey,
+ ExtractOrCreateKeyCallback aCallback,
+ void* aClosure,
+ bool aCallGetters) const
{
NS_ASSERTION(IsString(), "This doesn't make sense!");
@@ -455,7 +463,7 @@ KeyPath::ExtractOrCreateKey(JSContext* aCx, const JS::Value& aValue,
return rv;
}
- if (NS_FAILED(aKey.AppendItem(aCx, false, value))) {
+ if (NS_FAILED(aKey.AppendItem(aCx, false, value, aCallGetters))) {
NS_ASSERTION(aKey.IsUnset(), "Should be unset");
return value.isUndefined() ? NS_OK : NS_ERROR_DOM_INDEXEDDB_DATA_ERR;
}
diff --git a/dom/indexedDB/KeyPath.h b/dom/indexedDB/KeyPath.h
index c133cdc4a..e6e5f57d4 100644
--- a/dom/indexedDB/KeyPath.h
+++ b/dom/indexedDB/KeyPath.h
@@ -72,7 +72,10 @@ public:
Parse(const Nullable<OwningStringOrStringSequence>& aValue, KeyPath* aKeyPath);
nsresult
- ExtractKey(JSContext* aCx, const JS::Value& aValue, Key& aKey) const;
+ ExtractKey(JSContext* aCx,
+ const JS::Value& aValue,
+ Key& aKey,
+ bool aCallGetters) const;
nsresult
ExtractKeyAsJSVal(JSContext* aCx, const JS::Value& aValue,
@@ -82,9 +85,12 @@ public:
(*ExtractOrCreateKeyCallback)(JSContext* aCx, void* aClosure);
nsresult
- ExtractOrCreateKey(JSContext* aCx, const JS::Value& aValue, Key& aKey,
+ ExtractOrCreateKey(JSContext* aCx,
+ const JS::Value& aValue,
+ Key& aKey,
ExtractOrCreateKeyCallback aCallback,
- void* aClosure) const;
+ void* aClosure,
+ bool aCallGetters) const;
inline bool IsValid() const {
return mType != NONEXISTENT;
diff --git a/dom/indexedDB/crashtests/1558522-1.html b/dom/indexedDB/crashtests/1558522-1.html
new file mode 100644
index 000000000..47dd2f843
--- /dev/null
+++ b/dom/indexedDB/crashtests/1558522-1.html
@@ -0,0 +1,40 @@
+<html>
+<head>
+ <script id='worker' type='javascript/worker'>
+ onmessage = function (e) {
+ const file = e.data[0]
+ const db = indexedDB.open('', {})
+ db.onupgradeneeded = function (event) {
+ const store = event.target.result.createObjectStore('IDBStore_0', {})
+ store.add({}, '')
+ }
+ db.onsuccess = function (event) {
+ const transaction = event.target.result.transaction('IDBStore_0', 'readwrite')
+ const store = transaction.objectStore('IDBStore_0')
+ const cursor = store.openCursor()
+ cursor.onsuccess = function (event) {
+ event.target.result.update({
+ data: file
+ })
+ event.target.result.advance(1)
+ }
+
+ event.target.result.close()
+ }
+ }
+
+ </script>
+ <script>
+ let worker;
+
+ function start () {
+ const file = new File([], 'x')
+ const blob = new Blob([document.getElementById('worker').textContent], { type: 'text/javascript' })
+ worker = new Worker(window.URL.createObjectURL(blob))
+ worker.postMessage([file], [])
+ }
+
+ document.addEventListener('DOMContentLoaded', start)
+ </script>
+</head>
+</html> \ No newline at end of file
diff --git a/dom/indexedDB/crashtests/crashtests.list b/dom/indexedDB/crashtests/crashtests.list
index 69f5dab0b..ead6024dc 100644
--- a/dom/indexedDB/crashtests/crashtests.list
+++ b/dom/indexedDB/crashtests/crashtests.list
@@ -1 +1,2 @@
load 726376-1.html
+load 1558522-1.html
diff --git a/dom/indexedDB/test/helpers.js b/dom/indexedDB/test/helpers.js
index e6e27f3f3..ffe66ebcd 100644
--- a/dom/indexedDB/test/helpers.js
+++ b/dom/indexedDB/test/helpers.js
@@ -217,10 +217,6 @@ if (!window.runTest) {
function finishTest()
{
- SpecialPowers.notifyObserversInParentProcess(null,
- "disk-space-watcher",
- "free");
-
SimpleTest.executeSoon(function() {
testGenerator.close();
testHarnessGenerator.close();
diff --git a/dom/indexedDB/test/mochitest.ini b/dom/indexedDB/test/mochitest.ini
index 4ab55a9dc..ca65ea8b6 100644
--- a/dom/indexedDB/test/mochitest.ini
+++ b/dom/indexedDB/test/mochitest.ini
@@ -66,7 +66,6 @@ support-files =
unit/test_locale_aware_indexes.js
unit/test_locale_aware_index_getAll.js
unit/test_locale_aware_index_getAllObjects.js
- unit/test_lowDiskSpace.js
unit/test_maximal_serialized_object_size.js
unit/test_multientry.js
unit/test_names_sorted.js
@@ -214,7 +213,6 @@ skip-if = true
[test_key_requirements.html]
[test_keys.html]
[test_leaving_page.html]
-[test_lowDiskSpace.html]
[test_maximal_serialized_object_size.html]
[test_message_manager_ipc.html]
# This test is only supposed to run in the main process.
diff --git a/dom/indexedDB/test/test_lowDiskSpace.html b/dom/indexedDB/test/test_lowDiskSpace.html
deleted file mode 100644
index cffd46549..000000000
--- a/dom/indexedDB/test/test_lowDiskSpace.html
+++ /dev/null
@@ -1,19 +0,0 @@
-<!--
- Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/
--->
-<html>
-<head>
- <title>Indexed Database Low Disk Space Test</title>
-
- <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
- <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
-
- <script type="text/javascript;version=1.7" src="unit/test_lowDiskSpace.js"></script>
- <script type="text/javascript;version=1.7" src="helpers.js"></script>
-
-</head>
-
-<body onload="runTest();"></body>
-
-</html>
diff --git a/dom/indexedDB/test/unit/test_lowDiskSpace.js b/dom/indexedDB/test/unit/test_lowDiskSpace.js
deleted file mode 100644
index eaea5797d..000000000
--- a/dom/indexedDB/test/unit/test_lowDiskSpace.js
+++ /dev/null
@@ -1,754 +0,0 @@
-/**
- * Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/
- */
-"use strict";
-
-var disableWorkerTest = "This test uses SpecialPowers";
-
-var self = this;
-
-var testGenerator = testSteps();
-
-function testSteps()
-{
- const dbName = self.window ? window.location.pathname : "test_lowDiskSpace";
- const dbVersion = 1;
-
- const objectStoreName = "foo";
- const objectStoreOptions = { keyPath: "foo" };
-
- const indexName = "bar";
- const indexOptions = { unique: true };
-
- const dbData = [
- { foo: 0, bar: 0 },
- { foo: 1, bar: 10 },
- { foo: 2, bar: 20 },
- { foo: 3, bar: 30 },
- { foo: 4, bar: 40 },
- { foo: 5, bar: 50 },
- { foo: 6, bar: 60 },
- { foo: 7, bar: 70 },
- { foo: 8, bar: 80 },
- { foo: 9, bar: 90 }
- ];
-
- let lowDiskMode = false;
- function setLowDiskMode(val) {
- let data = val ? "full" : "free";
-
- if (val == lowDiskMode) {
- info("Low disk mode is: " + data);
- }
- else {
- info("Changing low disk mode to: " + data);
- SpecialPowers.notifyObserversInParentProcess(null, "disk-space-watcher",
- data);
- lowDiskMode = val;
- }
- }
-
- { // Make sure opening works from the beginning.
- info("Test 1");
-
- setLowDiskMode(false);
-
- let request = indexedDB.open(dbName, dbVersion);
- request.onerror = errorHandler;
- request.onsuccess = grabEventAndContinueHandler;
- let event = yield undefined;
-
- is(event.type, "success", "Opened database without setting low disk mode");
-
- let db = event.target.result;
- db.close();
- }
-
- { // Make sure delete works in low disk mode.
- info("Test 2");
-
- setLowDiskMode(true);
-
- let request = indexedDB.deleteDatabase(dbName);
- request.onerror = errorHandler;
- request.onsuccess = grabEventAndContinueHandler;
- let event = yield undefined;
-
- is(event.type, "success", "Deleted database after setting low disk mode");
- }
-
- { // Make sure creating a db in low disk mode fails.
- info("Test 3");
-
- setLowDiskMode(true);
-
- let request = indexedDB.open(dbName, dbVersion);
- request.onerror = expectedErrorHandler("QuotaExceededError");
- request.onupgradeneeded = unexpectedSuccessHandler;
- request.onsuccess = unexpectedSuccessHandler;
- let event = yield undefined;
-
- is(event.type, "error", "Didn't create new database in low disk mode");
- }
-
- { // Make sure opening an already-existing db in low disk mode succeeds.
- info("Test 4");
-
- setLowDiskMode(false);
-
- let request = indexedDB.open(dbName, dbVersion);
- request.onerror = errorHandler;
- request.onupgradeneeded = grabEventAndContinueHandler;
- request.onsuccess = unexpectedSuccessHandler;
- let event = yield undefined;
-
- is(event.type, "upgradeneeded", "Upgrading database");
-
- let db = event.target.result;
- db.onerror = errorHandler;
-
- request.onupgradeneeded = unexpectedSuccessHandler;
- request.onsuccess = grabEventAndContinueHandler;
- event = yield undefined;
-
- is(event.type, "success", "Created database");
- ok(event.target.result === db, "Got the same database");
-
- db.close();
-
- setLowDiskMode(true);
-
- request = indexedDB.open(dbName);
- request.onerror = errorHandler;
- request.onupgradeneeded = unexpectedSuccessHandler;
- request.onsuccess = grabEventAndContinueHandler;
- event = yield undefined;
-
- is(event.type, "success", "Opened existing database in low disk mode");
-
- db = event.target.result;
- db.close();
- }
-
- { // Make sure upgrading an already-existing db in low disk mode succeeds.
- info("Test 5");
-
- setLowDiskMode(true);
-
- let request = indexedDB.open(dbName, dbVersion + 1);
- request.onerror = errorHandler;
- request.onupgradeneeded = grabEventAndContinueHandler;
- request.onsuccess = unexpectedSuccessHandler;
-
- let event = yield undefined;
-
- is(event.type, "upgradeneeded", "Upgrading database");
-
- let db = event.target.result;
- db.onerror = errorHandler;
-
- request.onupgradeneeded = unexpectedSuccessHandler;
- request.onsuccess = grabEventAndContinueHandler;
- event = yield undefined;
-
- is(event.type, "success", "Created database");
- ok(event.target.result === db, "Got the same database");
-
- db.close();
- }
-
- { // Make sure creating objectStores in low disk mode fails.
- info("Test 6");
-
- setLowDiskMode(true);
-
- let request = indexedDB.open(dbName, dbVersion + 2);
- request.onerror = errorHandler;
- request.onupgradeneeded = grabEventAndContinueHandler;
- request.onsuccess = unexpectedSuccessHandler;
-
- let event = yield undefined;
-
- is(event.type, "upgradeneeded", "Upgrading database");
-
- let db = event.target.result;
- db.onerror = errorHandler;
-
- let txn = event.target.transaction;
- txn.onerror = expectedErrorHandler("AbortError");
- txn.onabort = grabEventAndContinueHandler;
-
- let objectStore = db.createObjectStore(objectStoreName, objectStoreOptions);
-
- request.onupgradeneeded = unexpectedSuccessHandler;
- event = yield undefined;
-
- is(event.type, "abort", "Got correct event type");
- is(event.target.error.name, "QuotaExceededError", "Got correct error type");
-
- request.onerror = expectedErrorHandler("AbortError");
- event = yield undefined;
- }
-
- { // Make sure creating indexes in low disk mode fails.
- info("Test 7");
-
- setLowDiskMode(false);
-
- let request = indexedDB.open(dbName, dbVersion + 2);
- request.onerror = errorHandler;
- request.onupgradeneeded = grabEventAndContinueHandler;
- request.onsuccess = unexpectedSuccessHandler;
-
- let event = yield undefined;
-
- is(event.type, "upgradeneeded", "Upgrading database");
-
- let db = event.target.result;
- db.onerror = errorHandler;
-
- let objectStore = db.createObjectStore(objectStoreName, objectStoreOptions);
-
- request.onupgradeneeded = unexpectedSuccessHandler;
- request.onsuccess = grabEventAndContinueHandler;
- event = yield undefined;
-
- is(event.type, "success", "Upgraded database");
- ok(event.target.result === db, "Got the same database");
-
- db.close();
-
- setLowDiskMode(true);
-
- request = indexedDB.open(dbName, dbVersion + 3);
- request.onerror = errorHandler;
- request.onupgradeneeded = grabEventAndContinueHandler;
- request.onsuccess = unexpectedSuccessHandler;
- event = yield undefined;
-
- is(event.type, "upgradeneeded", "Upgrading database");
-
- db = event.target.result;
- db.onerror = errorHandler;
- let txn = event.target.transaction;
- txn.onerror = expectedErrorHandler("AbortError");
- txn.onabort = grabEventAndContinueHandler;
-
- objectStore = event.target.transaction.objectStore(objectStoreName);
- let index = objectStore.createIndex(indexName, indexName, indexOptions);
-
- request.onupgradeneeded = unexpectedSuccessHandler;
- event = yield undefined;
-
- is(event.type, "abort", "Got correct event type");
- is(event.target.error.name, "QuotaExceededError", "Got correct error type");
-
- request.onerror = expectedErrorHandler("AbortError");
- event = yield undefined;
- }
-
- { // Make sure deleting indexes in low disk mode succeeds.
- info("Test 8");
-
- setLowDiskMode(false);
-
- let request = indexedDB.open(dbName, dbVersion + 3);
- request.onerror = errorHandler;
- request.onupgradeneeded = grabEventAndContinueHandler;
- request.onsuccess = unexpectedSuccessHandler;
-
- let event = yield undefined;
-
- is(event.type, "upgradeneeded", "Upgrading database");
-
- let db = event.target.result;
- db.onerror = errorHandler;
-
- let objectStore = event.target.transaction.objectStore(objectStoreName);
- let index = objectStore.createIndex(indexName, indexName, indexOptions);
-
- request.onupgradeneeded = unexpectedSuccessHandler;
- request.onsuccess = grabEventAndContinueHandler;
- event = yield undefined;
-
- is(event.type, "success", "Upgraded database");
- ok(event.target.result === db, "Got the same database");
-
- db.close();
-
- setLowDiskMode(true);
-
- request = indexedDB.open(dbName, dbVersion + 4);
- request.onerror = errorHandler;
- request.onupgradeneeded = grabEventAndContinueHandler;
- request.onsuccess = unexpectedSuccessHandler;
- event = yield undefined;
-
- is(event.type, "upgradeneeded", "Upgrading database");
-
- db = event.target.result;
- db.onerror = errorHandler;
-
- objectStore = event.target.transaction.objectStore(objectStoreName);
- objectStore.deleteIndex(indexName);
-
- request.onupgradeneeded = unexpectedSuccessHandler;
- request.onsuccess = grabEventAndContinueHandler;
- event = yield undefined;
-
- is(event.type, "success", "Upgraded database");
- ok(event.target.result === db, "Got the same database");
-
- db.close();
- }
-
- { // Make sure deleting objectStores in low disk mode succeeds.
- info("Test 9");
-
- setLowDiskMode(true);
-
- let request = indexedDB.open(dbName, dbVersion + 5);
- request.onerror = errorHandler;
- request.onupgradeneeded = grabEventAndContinueHandler;
- request.onsuccess = unexpectedSuccessHandler;
-
- let event = yield undefined;
-
- is(event.type, "upgradeneeded", "Upgrading database");
-
- let db = event.target.result;
- db.onerror = errorHandler;
-
- db.deleteObjectStore(objectStoreName);
-
- request.onupgradeneeded = unexpectedSuccessHandler;
- request.onsuccess = grabEventAndContinueHandler;
- event = yield undefined;
-
- is(event.type, "success", "Upgraded database");
- ok(event.target.result === db, "Got the same database");
-
- db.close();
-
- // Reset everything.
- indexedDB.deleteDatabase(dbName);
- }
-
-
- { // Add data that the rest of the tests will use.
- info("Adding test data");
-
- setLowDiskMode(false);
-
- let request = indexedDB.open(dbName, dbVersion);
- request.onerror = errorHandler;
- request.onupgradeneeded = grabEventAndContinueHandler;
- request.onsuccess = unexpectedSuccessHandler;
- let event = yield undefined;
-
- is(event.type, "upgradeneeded", "Upgrading database");
-
- let db = event.target.result;
- db.onerror = errorHandler;
-
- let objectStore = db.createObjectStore(objectStoreName, objectStoreOptions);
- let index = objectStore.createIndex(indexName, indexName, indexOptions);
-
- for (let data of dbData) {
- objectStore.add(data);
- }
-
- request.onupgradeneeded = unexpectedSuccessHandler;
- request.onsuccess = grabEventAndContinueHandler;
- event = yield undefined;
-
- is(event.type, "success", "Upgraded database");
- ok(event.target.result === db, "Got the same database");
-
- db.close();
- }
-
- { // Make sure read operations in readonly transactions succeed in low disk
- // mode.
- info("Test 10");
-
- setLowDiskMode(true);
-
- let request = indexedDB.open(dbName, dbVersion);
- request.onerror = errorHandler;
- request.onupgradeneeded = unexpectedSuccessHandler;
- request.onsuccess = grabEventAndContinueHandler;
- let event = yield undefined;
-
- let db = event.target.result;
- db.onerror = errorHandler;
-
- let transaction = db.transaction(objectStoreName);
- let objectStore = transaction.objectStore(objectStoreName);
- let index = objectStore.index(indexName);
-
- let data = dbData[0];
-
- let requestCounter = new RequestCounter();
-
- objectStore.get(data.foo).onsuccess = requestCounter.handler();
- objectStore.mozGetAll().onsuccess = requestCounter.handler();
- objectStore.count().onsuccess = requestCounter.handler();
- index.get(data.bar).onsuccess = requestCounter.handler();
- index.mozGetAll().onsuccess = requestCounter.handler();
- index.getKey(data.bar).onsuccess = requestCounter.handler();
- index.mozGetAllKeys().onsuccess = requestCounter.handler();
- index.count().onsuccess = requestCounter.handler();
-
- let objectStoreDataCount = 0;
-
- request = objectStore.openCursor();
- request.onsuccess = function(event) {
- let cursor = event.target.result;
- if (cursor) {
- objectStoreDataCount++;
- objectStoreDataCount % 2 ? cursor.continue() : cursor.advance(1);
- }
- else {
- is(objectStoreDataCount, dbData.length, "Saw all data");
- requestCounter.decr();
- }
- };
- requestCounter.incr();
-
- let indexDataCount = 0;
-
- request = index.openCursor();
- request.onsuccess = function(event) {
- let cursor = event.target.result;
- if (cursor) {
- indexDataCount++;
- indexDataCount % 2 ? cursor.continue() : cursor.advance(1);
- }
- else {
- is(indexDataCount, dbData.length, "Saw all data");
- requestCounter.decr();
- }
- };
- requestCounter.incr();
-
- let indexKeyDataCount = 0;
-
- request = index.openCursor();
- request.onsuccess = function(event) {
- let cursor = event.target.result;
- if (cursor) {
- indexKeyDataCount++;
- indexKeyDataCount % 2 ? cursor.continue() : cursor.advance(1);
- }
- else {
- is(indexKeyDataCount, dbData.length, "Saw all data");
- requestCounter.decr();
- }
- };
- requestCounter.incr();
-
- // Wait for all requests.
- yield undefined;
-
- transaction.oncomplete = grabEventAndContinueHandler;
- event = yield undefined;
-
- is(event.type, "complete", "Transaction succeeded");
-
- db.close();
- }
-
- { // Make sure read operations in readwrite transactions succeed in low disk
- // mode.
- info("Test 11");
-
- setLowDiskMode(true);
-
- let request = indexedDB.open(dbName, dbVersion);
- request.onerror = errorHandler;
- request.onupgradeneeded = unexpectedSuccessHandler;
- request.onsuccess = grabEventAndContinueHandler;
- let event = yield undefined;
-
- let db = event.target.result;
- db.onerror = errorHandler;
-
- let transaction = db.transaction(objectStoreName, "readwrite");
- let objectStore = transaction.objectStore(objectStoreName);
- let index = objectStore.index(indexName);
-
- let data = dbData[0];
-
- let requestCounter = new RequestCounter();
-
- objectStore.get(data.foo).onsuccess = requestCounter.handler();
- objectStore.mozGetAll().onsuccess = requestCounter.handler();
- objectStore.count().onsuccess = requestCounter.handler();
- index.get(data.bar).onsuccess = requestCounter.handler();
- index.mozGetAll().onsuccess = requestCounter.handler();
- index.getKey(data.bar).onsuccess = requestCounter.handler();
- index.mozGetAllKeys().onsuccess = requestCounter.handler();
- index.count().onsuccess = requestCounter.handler();
-
- let objectStoreDataCount = 0;
-
- request = objectStore.openCursor();
- request.onsuccess = function(event) {
- let cursor = event.target.result;
- if (cursor) {
- objectStoreDataCount++;
- objectStoreDataCount % 2 ? cursor.continue() : cursor.advance(1);
- }
- else {
- is(objectStoreDataCount, dbData.length, "Saw all data");
- requestCounter.decr();
- }
- };
- requestCounter.incr();
-
- let indexDataCount = 0;
-
- request = index.openCursor();
- request.onsuccess = function(event) {
- let cursor = event.target.result;
- if (cursor) {
- indexDataCount++;
- indexDataCount % 2 ? cursor.continue() : cursor.advance(1);
- }
- else {
- is(indexDataCount, dbData.length, "Saw all data");
- requestCounter.decr();
- }
- };
- requestCounter.incr();
-
- let indexKeyDataCount = 0;
-
- request = index.openCursor();
- request.onsuccess = function(event) {
- let cursor = event.target.result;
- if (cursor) {
- indexKeyDataCount++;
- indexKeyDataCount % 2 ? cursor.continue() : cursor.advance(1);
- }
- else {
- is(indexKeyDataCount, dbData.length, "Saw all data");
- requestCounter.decr();
- }
- };
- requestCounter.incr();
-
- // Wait for all requests.
- yield undefined;
-
- transaction.oncomplete = grabEventAndContinueHandler;
- event = yield undefined;
-
- is(event.type, "complete", "Transaction succeeded");
-
- db.close();
- }
-
- { // Make sure write operations in readwrite transactions fail in low disk
- // mode.
- info("Test 12");
-
- setLowDiskMode(true);
-
- let request = indexedDB.open(dbName, dbVersion);
- request.onerror = errorHandler;
- request.onupgradeneeded = unexpectedSuccessHandler;
- request.onsuccess = grabEventAndContinueHandler;
- let event = yield undefined;
-
- let db = event.target.result;
- db.onerror = errorHandler;
-
- let transaction = db.transaction(objectStoreName, "readwrite");
- let objectStore = transaction.objectStore(objectStoreName);
- let index = objectStore.index(indexName);
-
- let data = dbData[0];
- let newData = { foo: 999, bar: 999 };
-
- let requestCounter = new RequestCounter();
-
- objectStore.add(newData).onerror = requestCounter.errorHandler();
- objectStore.put(newData).onerror = requestCounter.errorHandler();
-
- objectStore.get(data.foo).onsuccess = requestCounter.handler();
- objectStore.mozGetAll().onsuccess = requestCounter.handler();
- objectStore.count().onsuccess = requestCounter.handler();
- index.get(data.bar).onsuccess = requestCounter.handler();
- index.mozGetAll().onsuccess = requestCounter.handler();
- index.getKey(data.bar).onsuccess = requestCounter.handler();
- index.mozGetAllKeys().onsuccess = requestCounter.handler();
- index.count().onsuccess = requestCounter.handler();
-
- let objectStoreDataCount = 0;
-
- request = objectStore.openCursor();
- request.onsuccess = function(event) {
- let cursor = event.target.result;
- if (cursor) {
- objectStoreDataCount++;
- cursor.update(cursor.value).onerror = requestCounter.errorHandler();
- objectStoreDataCount % 2 ? cursor.continue() : cursor.advance(1);
- }
- else {
- is(objectStoreDataCount, dbData.length, "Saw all data");
- requestCounter.decr();
- }
- };
- requestCounter.incr();
-
- let indexDataCount = 0;
-
- request = index.openCursor();
- request.onsuccess = function(event) {
- let cursor = event.target.result;
- if (cursor) {
- indexDataCount++;
- cursor.update(cursor.value).onerror = requestCounter.errorHandler();
- indexDataCount % 2 ? cursor.continue() : cursor.advance(1);
- }
- else {
- is(indexDataCount, dbData.length, "Saw all data");
- requestCounter.decr();
- }
- };
- requestCounter.incr();
-
- let indexKeyDataCount = 0;
-
- request = index.openCursor();
- request.onsuccess = function(event) {
- let cursor = event.target.result;
- if (cursor) {
- indexKeyDataCount++;
- cursor.update(cursor.value).onerror = requestCounter.errorHandler();
- indexKeyDataCount % 2 ? cursor.continue() : cursor.advance(1);
- }
- else {
- is(indexKeyDataCount, dbData.length, "Saw all data");
- requestCounter.decr();
- }
- };
- requestCounter.incr();
-
- // Wait for all requests.
- yield undefined;
-
- transaction.oncomplete = grabEventAndContinueHandler;
- event = yield undefined;
-
- is(event.type, "complete", "Transaction succeeded");
-
- db.close();
- }
-
- { // Make sure deleting operations in readwrite transactions succeed in low
- // disk mode.
- info("Test 13");
-
- setLowDiskMode(true);
-
- let request = indexedDB.open(dbName, dbVersion);
- request.onerror = errorHandler;
- request.onupgradeneeded = unexpectedSuccessHandler;
- request.onsuccess = grabEventAndContinueHandler;
- let event = yield undefined;
-
- let db = event.target.result;
- db.onerror = errorHandler;
-
- let transaction = db.transaction(objectStoreName, "readwrite");
- let objectStore = transaction.objectStore(objectStoreName);
- let index = objectStore.index(indexName);
-
- let dataIndex = 0;
- let data = dbData[dataIndex++];
-
- let requestCounter = new RequestCounter();
-
- objectStore.delete(data.foo).onsuccess = requestCounter.handler();
-
- objectStore.openCursor().onsuccess = function(event) {
- let cursor = event.target.result;
- if (cursor) {
- cursor.delete().onsuccess = requestCounter.handler();
- }
- requestCounter.decr();
- };
- requestCounter.incr();
-
- index.openCursor(null, "prev").onsuccess = function(event) {
- let cursor = event.target.result;
- if (cursor) {
- cursor.delete().onsuccess = requestCounter.handler();
- }
- requestCounter.decr();
- };
- requestCounter.incr();
-
- yield undefined;
-
- objectStore.count().onsuccess = grabEventAndContinueHandler;
- event = yield undefined;
-
- is(event.target.result, dbData.length - 3, "Actually deleted something");
-
- objectStore.clear();
- objectStore.count().onsuccess = grabEventAndContinueHandler;
- event = yield undefined;
-
- is(event.target.result, 0, "Actually cleared");
-
- transaction.oncomplete = grabEventAndContinueHandler;
- event = yield undefined;
-
- is(event.type, "complete", "Transaction succeeded");
-
- db.close();
- }
-
- finishTest();
- yield undefined;
-}
-
-function RequestCounter(expectedType) {
- this._counter = 0;
-}
-RequestCounter.prototype = {
- incr: function() {
- this._counter++;
- },
-
- decr: function() {
- if (!--this._counter) {
- continueToNextStepSync();
- }
- },
-
- handler: function(type, preventDefault) {
- this.incr();
- return function(event) {
- is(event.type, type || "success", "Correct type");
- this.decr();
- }.bind(this);
- },
-
- errorHandler: function(eventType, errorName) {
- this.incr();
- return function(event) {
- is(event.type, eventType || "error", "Correct type");
- is(event.target.error.name, errorName || "QuotaExceededError",
- "Correct error name");
- event.preventDefault();
- event.stopPropagation();
- this.decr();
- }.bind(this);
- }
-};
diff --git a/dom/indexedDB/test/unit/xpcshell-head-parent-process.js b/dom/indexedDB/test/unit/xpcshell-head-parent-process.js
index def791f52..fe69b1f7b 100644
--- a/dom/indexedDB/test/unit/xpcshell-head-parent-process.js
+++ b/dom/indexedDB/test/unit/xpcshell-head-parent-process.js
@@ -66,9 +66,6 @@ function finishTest()
resetWasm();
resetExperimental();
resetTesting();
-
- SpecialPowers.notifyObserversInParentProcess(null, "disk-space-watcher",
- "free");
}
SpecialPowers.removeFiles();
diff --git a/dom/indexedDB/test/unit/xpcshell-parent-process.ini b/dom/indexedDB/test/unit/xpcshell-parent-process.ini
index 04df5f552..2def60c34 100644
--- a/dom/indexedDB/test/unit/xpcshell-parent-process.ini
+++ b/dom/indexedDB/test/unit/xpcshell-parent-process.ini
@@ -46,7 +46,6 @@ skip-if = toolkit == 'android'
[test_invalidate.js]
# disabled for the moment.
skip-if = true
-[test_lowDiskSpace.js]
[test_maximal_serialized_object_size.js]
[test_metadata2Restore.js]
[test_metadataRestore.js]