Title: [117808] trunk
Revision
117808
Author
[email protected]
Date
2012-05-21 12:28:01 -0700 (Mon, 21 May 2012)

Log Message

IndexedDB: Index key paths that yield invalid keys should not fail an add/put
https://bugs.webkit.org/show_bug.cgi?id=86122

Reviewed by Tony Chang.

Source/WebCore:

A clause was removed from the IDB spec. Previously, on add/put, if evaluating an
index's key path yielded a value that was not a valid key, an exception would be
raised. Now, it is treated the same as if no value was yielded.

Test: storage/indexeddb/index-basics.html
Test: storage/indexeddb/index-basics-workers.html
Test: storage/indexeddb/objectstore-basics.html
Test: storage/indexeddb/objectstore-basics-workers.html

* Modules/indexeddb/IDBObjectStoreBackendImpl.cpp:
(WebCore::IDBObjectStoreBackendImpl::put): Preconditions removed
(WebCore::IDBObjectStoreBackendImpl::putInternal): Treat invalid keys the same as missing keys.

LayoutTests:

* storage/indexeddb/index-basics-expected.txt:
* storage/indexeddb/index-basics-workers-expected.txt:
* storage/indexeddb/objectstore-basics-expected.txt:
* storage/indexeddb/objectstore-basics-workers-expected.txt:
* storage/indexeddb/resources/index-basics.js: Add checks that index key paths
that evaluate to invalid keys do not fail puts/adds, just don't add index entries.
(addData3):
(addData4):
(cursor1Continue3):
(cursor1Continue4):
(cursor2Continue3):
(cursor2Continue4):
(last):
(index1Count):
(index2Count):
* storage/indexeddb/resources/objectstore-basics.js: Remove precondition checks
that would previously raise an exception if invalid keys were specified.
(addAgainFailure):
(testPreConditions.request.onsuccess):
(testPreConditions):

Modified Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (117807 => 117808)


--- trunk/LayoutTests/ChangeLog	2012-05-21 19:24:38 UTC (rev 117807)
+++ trunk/LayoutTests/ChangeLog	2012-05-21 19:28:01 UTC (rev 117808)
@@ -1,5 +1,33 @@
 2012-05-21  Joshua Bell  <[email protected]>
 
+        IndexedDB: Index key paths that yield invalid keys should not fail an add/put
+        https://bugs.webkit.org/show_bug.cgi?id=86122
+
+        Reviewed by Tony Chang.
+
+        * storage/indexeddb/index-basics-expected.txt:
+        * storage/indexeddb/index-basics-workers-expected.txt:
+        * storage/indexeddb/objectstore-basics-expected.txt:
+        * storage/indexeddb/objectstore-basics-workers-expected.txt:
+        * storage/indexeddb/resources/index-basics.js: Add checks that index key paths
+        that evaluate to invalid keys do not fail puts/adds, just don't add index entries.
+        (addData3):
+        (addData4):
+        (cursor1Continue3):
+        (cursor1Continue4):
+        (cursor2Continue3):
+        (cursor2Continue4):
+        (last):
+        (index1Count):
+        (index2Count):
+        * storage/indexeddb/resources/objectstore-basics.js: Remove precondition checks
+        that would previously raise an exception if invalid keys were specified.
+        (addAgainFailure):
+        (testPreConditions.request.onsuccess):
+        (testPreConditions):
+
+2012-05-21  Joshua Bell  <[email protected]>
+
         LayoutTests: fast/js/resources/js-test-pre.js - shouldBeEqualToString fails on "
         https://bugs.webkit.org/show_bug.cgi?id=86931
 

Modified: trunk/LayoutTests/storage/indexeddb/index-basics-expected.txt (117807 => 117808)


--- trunk/LayoutTests/storage/indexeddb/index-basics-expected.txt	2012-05-21 19:24:38 UTC (rev 117807)
+++ trunk/LayoutTests/storage/indexeddb/index-basics-expected.txt	2012-05-21 19:28:01 UTC (rev 117808)
@@ -48,7 +48,10 @@
 event.target.source.add({x: 'value2', y: 'zzz2', z: 2.71, foobar: 12}, 'key2')
 store.createIndex('indexWhileAddIsInFlight', 'x')
 store.createIndex('indexWithWeirdKeyPath', 'foobar')
+Add data which doesn't have a key in the z index.
 event.target.source.add({x: 'value3', y: '456'}, 'key3')
+Add data which has invalid key for y index, no key for the z index.
+event.target.source.add({x: 'value4', y: null}, 'key4')
 indexObject.getKey('value')
 PASS event.target.result is "key"
 indexObject2.getKey('zzz')
@@ -78,6 +81,10 @@
 PASS event.target.result.key is "value3"
 PASS event.target.result.primaryKey is "key3"
 event.target.result.continue()
+PASS event.target.result is non-null.
+PASS event.target.result.key is "value4"
+PASS event.target.result.primaryKey is "key4"
+event.target.result.continue()
 PASS event.target.result is null
 indexObject.openCursor()
 PASS event.target.source is indexObject
@@ -96,7 +103,18 @@
 PASS event.target.result.value.x is "value3"
 PASS event.target.result.value.y is "456"
 event.target.result.continue()
+PASS event.target.result is non-null.
+PASS event.target.result.key is "value4"
+PASS event.target.result.value.x is "value4"
+PASS event.target.result.value.y is null
+event.target.result.continue()
 PASS event.target.result is null
+request = indexObject.count()
+PASS event.target.result is 4
+request = indexObject2.count()
+PASS event.target.result is 3
+request = indexObject3.count()
+PASS event.target.result is 2
 Passing an invalid key into indexObject.get({}).
 Expecting exception from indexObject.get({})
 PASS Exception was thrown.

Modified: trunk/LayoutTests/storage/indexeddb/index-basics-workers-expected.txt (117807 => 117808)


--- trunk/LayoutTests/storage/indexeddb/index-basics-workers-expected.txt	2012-05-21 19:24:38 UTC (rev 117807)
+++ trunk/LayoutTests/storage/indexeddb/index-basics-workers-expected.txt	2012-05-21 19:28:01 UTC (rev 117808)
@@ -49,7 +49,10 @@
 [Worker] event.target.source.add({x: 'value2', y: 'zzz2', z: 2.71, foobar: 12}, 'key2')
 [Worker] store.createIndex('indexWhileAddIsInFlight', 'x')
 [Worker] store.createIndex('indexWithWeirdKeyPath', 'foobar')
+[Worker] Add data which doesn't have a key in the z index.
 [Worker] event.target.source.add({x: 'value3', y: '456'}, 'key3')
+[Worker] Add data which has invalid key for y index, no key for the z index.
+[Worker] event.target.source.add({x: 'value4', y: null}, 'key4')
 [Worker] indexObject.getKey('value')
 PASS [Worker] event.target.result is "key"
 [Worker] indexObject2.getKey('zzz')
@@ -79,6 +82,10 @@
 PASS [Worker] event.target.result.key is "value3"
 PASS [Worker] event.target.result.primaryKey is "key3"
 [Worker] event.target.result.continue()
+PASS [Worker] event.target.result is non-null.
+PASS [Worker] event.target.result.key is "value4"
+PASS [Worker] event.target.result.primaryKey is "key4"
+[Worker] event.target.result.continue()
 PASS [Worker] event.target.result is null
 [Worker] indexObject.openCursor()
 PASS [Worker] event.target.source is indexObject
@@ -97,7 +104,18 @@
 PASS [Worker] event.target.result.value.x is "value3"
 PASS [Worker] event.target.result.value.y is "456"
 [Worker] event.target.result.continue()
+PASS [Worker] event.target.result is non-null.
+PASS [Worker] event.target.result.key is "value4"
+PASS [Worker] event.target.result.value.x is "value4"
+PASS [Worker] event.target.result.value.y is null
+[Worker] event.target.result.continue()
 PASS [Worker] event.target.result is null
+[Worker] request = indexObject.count()
+PASS [Worker] event.target.result is 4
+[Worker] request = indexObject2.count()
+PASS [Worker] event.target.result is 3
+[Worker] request = indexObject3.count()
+PASS [Worker] event.target.result is 2
 [Worker] Passing an invalid key into indexObject.get({}).
 [Worker] Expecting exception from indexObject.get({})
 PASS [Worker] Exception was thrown.

Modified: trunk/LayoutTests/storage/indexeddb/objectstore-basics-expected.txt (117807 => 117808)


--- trunk/LayoutTests/storage/indexeddb/objectstore-basics-expected.txt	2012-05-21 19:24:38 UTC (rev 117807)
+++ trunk/LayoutTests/storage/indexeddb/objectstore-basics-expected.txt	2012-05-21 19:28:01 UTC (rev 117808)
@@ -104,9 +104,8 @@
 PASS code is IDBDatabaseException.DATA_ERR
 db.transaction(['storeName'], 'readwrite')
 store = transaction.objectStore('storeName')
-Expecting exception from store.add({x: null}, 'validkey')
-PASS Exception was thrown.
-PASS code is IDBDatabaseException.DATA_ERR
+Ensure invalid key pointed at by index keyPath is ignored
+store.add({x: null}, 'validkey')
 db.transaction(['storeName'], 'readwrite')
 store = transaction.objectStore('storeName')
 store.get('key')
@@ -168,10 +167,6 @@
 Expecting exception from storeWithOutOfLineKeys.put({}, null)
 PASS Exception was thrown.
 PASS code is IDBDatabaseException.DATA_ERR
-If there are any indexes referencing this object store whose key path is a string, evaluating their key path on the value parameter yields a value, and that value is not a valid key.
-Expecting exception from storeWithIndex.put({indexKey: null}, 'key')
-PASS Exception was thrown.
-PASS code is IDBDatabaseException.DATA_ERR
 
 IDBObjectStore.add()
 The object store uses in-line keys and the key parameter was provided.
@@ -194,10 +189,6 @@
 Expecting exception from storeWithOutOfLineKeys.add({}, null)
 PASS Exception was thrown.
 PASS code is IDBDatabaseException.DATA_ERR
-If there are any indexes referencing this object store whose key path is a string, evaluating their key path on the value parameter yields a value, and that value is not a valid key.
-Expecting exception from storeWithIndex.add({indexKey: null}, 'key')
-PASS Exception was thrown.
-PASS code is IDBDatabaseException.DATA_ERR
 PASS successfullyParsed is true
 
 TEST COMPLETE

Modified: trunk/LayoutTests/storage/indexeddb/objectstore-basics-workers-expected.txt (117807 => 117808)


--- trunk/LayoutTests/storage/indexeddb/objectstore-basics-workers-expected.txt	2012-05-21 19:24:38 UTC (rev 117807)
+++ trunk/LayoutTests/storage/indexeddb/objectstore-basics-workers-expected.txt	2012-05-21 19:28:01 UTC (rev 117808)
@@ -105,9 +105,8 @@
 PASS [Worker] code is IDBDatabaseException.DATA_ERR
 [Worker] db.transaction(['storeName'], 'readwrite')
 [Worker] store = transaction.objectStore('storeName')
-[Worker] Expecting exception from store.add({x: null}, 'validkey')
-PASS [Worker] Exception was thrown.
-PASS [Worker] code is IDBDatabaseException.DATA_ERR
+[Worker] Ensure invalid key pointed at by index keyPath is ignored
+[Worker] store.add({x: null}, 'validkey')
 [Worker] db.transaction(['storeName'], 'readwrite')
 [Worker] store = transaction.objectStore('storeName')
 [Worker] store.get('key')
@@ -169,10 +168,6 @@
 [Worker] Expecting exception from storeWithOutOfLineKeys.put({}, null)
 PASS [Worker] Exception was thrown.
 PASS [Worker] code is IDBDatabaseException.DATA_ERR
-[Worker] If there are any indexes referencing this object store whose key path is a string, evaluating their key path on the value parameter yields a value, and that value is not a valid key.
-[Worker] Expecting exception from storeWithIndex.put({indexKey: null}, 'key')
-PASS [Worker] Exception was thrown.
-PASS [Worker] code is IDBDatabaseException.DATA_ERR
 [Worker] 
 [Worker] IDBObjectStore.add()
 [Worker] The object store uses in-line keys and the key parameter was provided.
@@ -195,10 +190,6 @@
 [Worker] Expecting exception from storeWithOutOfLineKeys.add({}, null)
 PASS [Worker] Exception was thrown.
 PASS [Worker] code is IDBDatabaseException.DATA_ERR
-[Worker] If there are any indexes referencing this object store whose key path is a string, evaluating their key path on the value parameter yields a value, and that value is not a valid key.
-[Worker] Expecting exception from storeWithIndex.add({indexKey: null}, 'key')
-PASS [Worker] Exception was thrown.
-PASS [Worker] code is IDBDatabaseException.DATA_ERR
 PASS successfullyParsed is true
 
 TEST COMPLETE

Modified: trunk/LayoutTests/storage/indexeddb/resources/index-basics.js (117807 => 117808)


--- trunk/LayoutTests/storage/indexeddb/resources/index-basics.js	2012-05-21 19:24:38 UTC (rev 117807)
+++ trunk/LayoutTests/storage/indexeddb/resources/index-basics.js	2012-05-21 19:28:01 UTC (rev 117808)
@@ -85,8 +85,17 @@
 function addData3(evt)
 {
     event = evt;
-    // Add data which doesn't have a key in the zIndex.
+    debug("Add data which doesn't have a key in the z index.");
     request = evalAndLog("event.target.source.add({x: 'value3', y: '456'}, 'key3')");
+    request._onsuccess_ = addData4;
+    request._onerror_ = unexpectedErrorCallback;
+}
+
+function addData4(evt)
+{
+    event = evt;
+    debug("Add data which has invalid key for y index, no key for the z index.");
+    request = evalAndLog("event.target.source.add({x: 'value4', y: null}, 'key4')");
     request._onsuccess_ = getData;
     request._onerror_ = unexpectedErrorCallback;
 }
@@ -204,6 +213,18 @@
 
     // We re-use the last request object.
     evalAndLog("event.target.result.continue()");
+    self.request._onsuccess_ = cursor1Continue4;
+}
+
+function cursor1Continue4(evt)
+{
+    event = evt;
+    shouldBeNonNull("event.target.result");
+    shouldBeEqualToString("event.target.result.key", "value4");
+    shouldBeEqualToString("event.target.result.primaryKey", "key4");
+
+    // We re-use the last request object.
+    evalAndLog("event.target.result.continue()");
     self.request._onsuccess_ = openObjectCursor;
 }
 
@@ -254,6 +275,19 @@
 
     // We re-use the last request object.
     evalAndLog("event.target.result.continue()");
+    self.request._onsuccess_ = cursor2Continue4;
+}
+
+function cursor2Continue4(evt)
+{
+    event = evt;
+    shouldBeNonNull("event.target.result");
+    shouldBeEqualToString("event.target.result.key", "value4");
+    shouldBeEqualToString("event.target.result.value.x", "value4");
+    shouldBe("event.target.result.value.y", "null");
+
+    // We re-use the last request object.
+    evalAndLog("event.target.result.continue()");
     self.request._onsuccess_ = last;
 }
 
@@ -262,6 +296,36 @@
     event = evt;
     shouldBeNull("event.target.result");
 
+    evalAndLog("request = indexObject.count()");
+    request._onerror_ = unexpectedErrorCallback;
+    request._onsuccess_ = index1Count;
+}
+
+function index1Count(evt)
+{
+    event = evt;
+    shouldBe("event.target.result", "4");
+
+    evalAndLog("request = indexObject2.count()");
+    request._onerror_ = unexpectedErrorCallback;
+    request._onsuccess_ = index2Count;
+}
+
+function index2Count(evt)
+{
+    event = evt;
+    shouldBe("event.target.result", "3");
+
+    evalAndLog("request = indexObject3.count()");
+    request._onerror_ = unexpectedErrorCallback;
+    request._onsuccess_ = index3Count;
+}
+
+function index3Count(evt)
+{
+    event = evt;
+    shouldBe("event.target.result", "2");
+
     debug("Passing an invalid key into indexObject.get({}).");
     evalAndExpectException("indexObject.get({})", "IDBDatabaseException.DATA_ERR");
 

Modified: trunk/LayoutTests/storage/indexeddb/resources/objectstore-basics.js (117807 => 117808)


--- trunk/LayoutTests/storage/indexeddb/resources/objectstore-basics.js	2012-05-21 19:24:38 UTC (rev 117807)
+++ trunk/LayoutTests/storage/indexeddb/resources/objectstore-basics.js	2012-05-21 19:28:01 UTC (rev 117808)
@@ -190,7 +190,8 @@
     transaction._onabort_ = unexpectedErrorCallback;
     store = evalAndLog("store = transaction.objectStore('storeName')");
 
-    evalAndExpectException("store.add({x: null}, 'validkey')", "IDBDatabaseException.DATA_ERR");
+    debug("Ensure invalid key pointed at by index keyPath is ignored");
+    evalAndLog("store.add({x: null}, 'validkey')");
 
     transaction = evalAndLog("db.transaction(['storeName'], 'readwrite')");
     transaction._onabort_ = unexpectedErrorCallback;
@@ -286,9 +287,6 @@
         debug("The key parameter was provided but does not contain a valid key.");
         evalAndExpectException("storeWithOutOfLineKeys.put({}, null)", "IDBDatabaseException.DATA_ERR");
 
-        debug("If there are any indexes referencing this object store whose key path is a string, evaluating their key path on the value parameter yields a value, and that value is not a valid key.");
-        evalAndExpectException("storeWithIndex.put({indexKey: null}, 'key')", "IDBDatabaseException.DATA_ERR");
-
         debug("");
         debug("IDBObjectStore.add()");
         debug("The object store uses in-line keys and the key parameter was provided.");
@@ -306,9 +304,6 @@
         debug("The key parameter was provided but does not contain a valid key.");
         evalAndExpectException("storeWithOutOfLineKeys.add({}, null)", "IDBDatabaseException.DATA_ERR");
 
-        debug("If there are any indexes referencing this object store whose key path is a string, evaluating their key path on the value parameter yields a value, and that value is not a valid key.");
-        evalAndExpectException("storeWithIndex.add({indexKey: null}, 'key')", "IDBDatabaseException.DATA_ERR");
-
         finishJSTest();
     };
 }

Modified: trunk/Source/WebCore/ChangeLog (117807 => 117808)


--- trunk/Source/WebCore/ChangeLog	2012-05-21 19:24:38 UTC (rev 117807)
+++ trunk/Source/WebCore/ChangeLog	2012-05-21 19:28:01 UTC (rev 117808)
@@ -1,3 +1,23 @@
+2012-05-21  Joshua Bell  <[email protected]>
+
+        IndexedDB: Index key paths that yield invalid keys should not fail an add/put
+        https://bugs.webkit.org/show_bug.cgi?id=86122
+
+        Reviewed by Tony Chang.
+
+        A clause was removed from the IDB spec. Previously, on add/put, if evaluating an
+        index's key path yielded a value that was not a valid key, an exception would be
+        raised. Now, it is treated the same as if no value was yielded.
+
+        Test: storage/indexeddb/index-basics.html
+        Test: storage/indexeddb/index-basics-workers.html
+        Test: storage/indexeddb/objectstore-basics.html
+        Test: storage/indexeddb/objectstore-basics-workers.html
+
+        * Modules/indexeddb/IDBObjectStoreBackendImpl.cpp:
+        (WebCore::IDBObjectStoreBackendImpl::put): Preconditions removed
+        (WebCore::IDBObjectStoreBackendImpl::putInternal): Treat invalid keys the same as missing keys.
+
 2012-05-21  Pavel Feldman  <[email protected]>
 
         Web Inspector: refactor revision history to not include resource itself.

Modified: trunk/Source/WebCore/Modules/indexeddb/IDBObjectStoreBackendImpl.cpp (117807 => 117808)


--- trunk/Source/WebCore/Modules/indexeddb/IDBObjectStoreBackendImpl.cpp	2012-05-21 19:24:38 UTC (rev 117807)
+++ trunk/Source/WebCore/Modules/indexeddb/IDBObjectStoreBackendImpl.cpp	2012-05-21 19:28:01 UTC (rev 117808)
@@ -205,14 +205,6 @@
             ec = IDBDatabaseException::DATA_ERR;
             return;
         }
-        for (IndexMap::iterator it = m_indexes.begin(); it != m_indexes.end(); ++it) {
-            const RefPtr<IDBIndexBackendImpl>& index = it->second;
-            RefPtr<IDBKey> indexKey = fetchKeyFromKeyPath(value.get(), index->keyPath());
-            if (indexKey && !indexKey->isValid()) {
-                ec = IDBDatabaseException::DATA_ERR;
-                return;
-            }
-        }
     } else {
         ASSERT(key);
         const bool hasKeyPath = !objectStore->m_keyPath.isNull();
@@ -293,8 +285,10 @@
         const RefPtr<IDBIndexBackendImpl>& index = it->second;
 
         RefPtr<IDBKey> indexKey = fetchKeyFromKeyPath(value.get(), index->keyPath());
-        if (!indexKey) {
-            indexKeys.append(indexKey.release());
+        if (!indexKey || !indexKey->isValid()) {
+            // Null/invalid keys not added to index; null entry keeps iterator/vector indexes consistent.
+            indexKey.clear();
+            indexKeys.append(indexKey);
             continue;
         }
         ASSERT(indexKey->isValid());
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to