- Revision
- 250936
- Author
- sihui_...@apple.com
- Date
- 2019-10-09 15:20:29 -0700 (Wed, 09 Oct 2019)
Log Message
IndexedDB: include size of index records in size estimate of put/add task
https://bugs.webkit.org/show_bug.cgi?id=202483
Reviewed by Geoffrey Garen.
Source/WebCore:
SQLiteIDBBackingStore has two tables IndexRecords and Records. For add operation add(VALUE, KEY), we add a new
record to Records table. If we can extract index value from VALUE for some index, we would add a new record to
IndexRecords table.
We estimated the task szie of add task with (KEY_SIZE + VALUE_SIZE), but we didn't count the size that could be
added to the IndexRecords table. This could lead to storage abuse.
Test: storage/indexeddb/request-size-estimate.html
* Modules/indexeddb/server/UniqueIDBDatabase.cpp:
(WebCore::IDBServer::UniqueIDBDatabase::putOrAdd):
LayoutTests:
* platform/mac-wk1/TestExpectations:
* platform/win/TestExpectations:
* platform/wincairo/TestExpectations:
* storage/indexeddb/request-size-estimate-expected.txt: Added.
* storage/indexeddb/request-size-estimate.html: Added.
* storage/indexeddb/resources/request-size-estimate.js: Added.
(randomKey):
(randomPropertyValue):
(createObject):
(prepareDatabase):
(onOpenSuccess):
Modified Paths
Added Paths
Diff
Modified: trunk/LayoutTests/ChangeLog (250935 => 250936)
--- trunk/LayoutTests/ChangeLog 2019-10-09 22:03:29 UTC (rev 250935)
+++ trunk/LayoutTests/ChangeLog 2019-10-09 22:20:29 UTC (rev 250936)
@@ -1,3 +1,22 @@
+2019-10-09 Sihui Liu <sihui_...@apple.com>
+
+ IndexedDB: include size of index records in size estimate of put/add task
+ https://bugs.webkit.org/show_bug.cgi?id=202483
+
+ Reviewed by Geoffrey Garen.
+
+ * platform/mac-wk1/TestExpectations:
+ * platform/win/TestExpectations:
+ * platform/wincairo/TestExpectations:
+ * storage/indexeddb/request-size-estimate-expected.txt: Added.
+ * storage/indexeddb/request-size-estimate.html: Added.
+ * storage/indexeddb/resources/request-size-estimate.js: Added.
+ (randomKey):
+ (randomPropertyValue):
+ (createObject):
+ (prepareDatabase):
+ (onOpenSuccess):
+
2019-10-09 Chris Dumez <cdu...@apple.com>
Youtube.com is unable to enter the back/forward cache on macOS
Modified: trunk/LayoutTests/platform/mac-wk1/TestExpectations (250935 => 250936)
--- trunk/LayoutTests/platform/mac-wk1/TestExpectations 2019-10-09 22:03:29 UTC (rev 250935)
+++ trunk/LayoutTests/platform/mac-wk1/TestExpectations 2019-10-09 22:20:29 UTC (rev 250936)
@@ -304,6 +304,7 @@
http/tests/IndexedDB/storage-limit-1.https.html [ Skip ]
http/tests/IndexedDB/storage-limit-2.https.html [ Skip ]
storage/indexeddb/storage-limit.html [ Skip ]
+storage/indexeddb/request-size-estimate.html [ Skip ]
# Skip WebRTC for now in WK1
imported/w3c/web-platform-tests/webrtc [ Skip ]
Modified: trunk/LayoutTests/platform/win/TestExpectations (250935 => 250936)
--- trunk/LayoutTests/platform/win/TestExpectations 2019-10-09 22:03:29 UTC (rev 250935)
+++ trunk/LayoutTests/platform/win/TestExpectations 2019-10-09 22:20:29 UTC (rev 250936)
@@ -2417,6 +2417,7 @@
http/tests/xmlhttprequest/web-apps/013.html
storage/indexeddb/storage-limit.html [ Skip ]
+storage/indexeddb/request-size-estimate.html [ Skip ]
http/tests/IndexedDB/storage-limit.https.html [ Skip ]
http/tests/IndexedDB/storage-limit-1.https.html [ Skip ]
http/tests/IndexedDB/storage-limit-2.https.html [ Skip ]
Modified: trunk/LayoutTests/platform/wincairo/TestExpectations (250935 => 250936)
--- trunk/LayoutTests/platform/wincairo/TestExpectations 2019-10-09 22:03:29 UTC (rev 250935)
+++ trunk/LayoutTests/platform/wincairo/TestExpectations 2019-10-09 22:20:29 UTC (rev 250936)
@@ -1471,6 +1471,7 @@
storage/indexeddb/objectstore-basics.html [ Failure Pass ]
storage/indexeddb/objectstore-cursor.html [ Pass Timeout ]
storage/indexeddb/storage-limit.html [ Failure ]
+storage/indexeddb/request-size-estimate.html [ Failure ]
storage/indexeddb/structured-clone.html [ Pass Timeout ]
storage/indexeddb/version-change-abort.html [ Failure Pass ]
storage/indexeddb/wasm-exceptions.html [ Failure ]
Added: trunk/LayoutTests/storage/indexeddb/request-size-estimate-expected.txt (0 => 250936)
--- trunk/LayoutTests/storage/indexeddb/request-size-estimate-expected.txt (rev 0)
+++ trunk/LayoutTests/storage/indexeddb/request-size-estimate-expected.txt 2019-10-09 22:20:29 UTC (rev 250936)
@@ -0,0 +1,24 @@
+This test verifies that estimated size of IDB database task is not smaller than or close to actual space increase (maybe subject to our implementation of backing store.)
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+indexedDB = self.indexedDB || self.webkitIndexedDB || self.mozIndexedDB || self.msIndexedDB || self.OIndexedDB;
+
+indexedDB.deleteDatabase(dbname)
+indexedDB.open(dbname)
+
+prepareDatabase():
+Create 20 indexes
+
+onOpenSuccess():
+db = event.target.result
+store = db.transaction('store', 'readwrite').objectStore('store')
+request = store.add(createObject(), randomKey(keySize))
+PASS 'error' in request is true
+PASS request.error.code is DOMException.QUOTA_EXCEEDED_ERR
+PASS request.error.name is "QuotaExceededError"
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Added: trunk/LayoutTests/storage/indexeddb/request-size-estimate.html (0 => 250936)
--- trunk/LayoutTests/storage/indexeddb/request-size-estimate.html (rev 0)
+++ trunk/LayoutTests/storage/indexeddb/request-size-estimate.html 2019-10-09 22:20:29 UTC (rev 250936)
@@ -0,0 +1,9 @@
+<html>
+<head>
+<script src=""
+<script src=""
+</head>
+<body>
+<script src=""
+</body>
+</html>
\ No newline at end of file
Added: trunk/LayoutTests/storage/indexeddb/resources/request-size-estimate.js (0 => 250936)
--- trunk/LayoutTests/storage/indexeddb/resources/request-size-estimate.js (rev 0)
+++ trunk/LayoutTests/storage/indexeddb/resources/request-size-estimate.js 2019-10-09 22:20:29 UTC (rev 250936)
@@ -0,0 +1,72 @@
+if (this.importScripts) {
+ importScripts('../../../resources/js-test.js');
+ importScripts('shared.js');
+}
+
+if (window.testRunner)
+ testRunner.setAllowStorageQuotaIncrease(false);
+
+description('This test verifies that estimated size of IDB database task is not smaller than or close to actual space increase (maybe subject to our implementation of backing store.)');
+
+const quota = 400 * 1024; // Current default quota for test.
+const indexCount = 20;
+const indexValueSize = 1024;
+const keySize = 1024;
+
+indexedDBTest(prepareDatabase, onOpenSuccess);
+
+function randomKey(length) {
+ var str = "";
+ for (var i = 0; i < length; i++)
+ str += (Math.floor(Math.random() * 10))
+ return str;
+}
+
+function randomPropertyValue(length) {
+ var value = [];
+ for (var i = 0; i < length; i++)
+ value.push(Math.floor(Math.random() * 10))
+ return value;
+}
+
+function createObject() {
+ var obj = { };
+ for (var i = 0; i < indexCount; i++)
+ obj["index" + i] = randomPropertyValue(indexValueSize);
+
+ return obj;
+}
+
+function prepareDatabase(event)
+{
+ preamble(event);
+ db = event.target.result;
+ store = db.createObjectStore('store');
+ var indexes = [];
+
+ debug("Create " + indexCount + " indexes");
+ // This is an extreme case where each of indexes is composed of all properties of the object.
+ for (var i = 0; i < indexCount; i ++)
+ indexes.push("index" + i);
+ for (var i = 0; i < indexCount; i ++)
+ store.createIndex("allIndexes" + i, indexes);
+}
+
+function onOpenSuccess(event)
+{
+ preamble(event);
+ evalAndLog("db = event.target.result");
+ evalAndLog("store = db.transaction('store', 'readwrite').objectStore('store')");
+ request = evalAndLog("request = store.add(createObject(), randomKey(keySize))");
+ request._onerror_ = () => {
+ shouldBeTrue("'error' in request");
+ shouldBe("request.error.code", "DOMException.QUOTA_EXCEEDED_ERR");
+ shouldBeEqualToString("request.error.name", "QuotaExceededError");
+
+ finishJSTest();
+ }
+ request._onsuccess_ = () => {
+ testFailed("Add operation should fail because task size is bigger than space available");
+ finishJSTest();
+ }
+}
\ No newline at end of file
Modified: trunk/Source/WebCore/ChangeLog (250935 => 250936)
--- trunk/Source/WebCore/ChangeLog 2019-10-09 22:03:29 UTC (rev 250935)
+++ trunk/Source/WebCore/ChangeLog 2019-10-09 22:20:29 UTC (rev 250936)
@@ -1,3 +1,22 @@
+2019-10-09 Sihui Liu <sihui_...@apple.com>
+
+ IndexedDB: include size of index records in size estimate of put/add task
+ https://bugs.webkit.org/show_bug.cgi?id=202483
+
+ Reviewed by Geoffrey Garen.
+
+ SQLiteIDBBackingStore has two tables IndexRecords and Records. For add operation add(VALUE, KEY), we add a new
+ record to Records table. If we can extract index value from VALUE for some index, we would add a new record to
+ IndexRecords table.
+
+ We estimated the task szie of add task with (KEY_SIZE + VALUE_SIZE), but we didn't count the size that could be
+ added to the IndexRecords table. This could lead to storage abuse.
+
+ Test: storage/indexeddb/request-size-estimate.html
+
+ * Modules/indexeddb/server/UniqueIDBDatabase.cpp:
+ (WebCore::IDBServer::UniqueIDBDatabase::putOrAdd):
+
2019-10-09 Chris Dumez <cdu...@apple.com>
Youtube.com is unable to enter the back/forward cache on macOS
Modified: trunk/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.cpp (250935 => 250936)
--- trunk/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.cpp 2019-10-09 22:03:29 UTC (rev 250935)
+++ trunk/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.cpp 2019-10-09 22:20:29 UTC (rev 250936)
@@ -1228,6 +1228,11 @@
LOG(IndexedDB, "(main) UniqueIDBDatabase::putOrAdd");
auto taskSize = defaultWriteOperationCost + estimateSize(keyData) + estimateSize(value);
+ ASSERT(m_databaseInfo);
+ auto* objectStore = m_databaseInfo->infoForExistingObjectStore(requestData.objectStoreIdentifier());
+ if (objectStore)
+ taskSize += objectStore->indexNames().size() * taskSize;
+
requestSpace(transaction, taskSize, "putOrAdd", [this, taskSize, requestData, keyData, value, callback = WTFMove(callback), overwriteMode](auto error) mutable {
if (!error.isNull() && *error.code() != QuotaExceededError) {
callback(WTFMove(error), { });