Changeset 117808 in webkit


Ignore:
Timestamp:
May 21, 2012 12:28:01 PM (12 years ago)
Author:
jsbell@chromium.org
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):

Location:
trunk
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r117806 r117808  
     12012-05-21  Joshua Bell  <jsbell@chromium.org>
     2
     3        IndexedDB: Index key paths that yield invalid keys should not fail an add/put
     4        https://bugs.webkit.org/show_bug.cgi?id=86122
     5
     6        Reviewed by Tony Chang.
     7
     8        * storage/indexeddb/index-basics-expected.txt:
     9        * storage/indexeddb/index-basics-workers-expected.txt:
     10        * storage/indexeddb/objectstore-basics-expected.txt:
     11        * storage/indexeddb/objectstore-basics-workers-expected.txt:
     12        * storage/indexeddb/resources/index-basics.js: Add checks that index key paths
     13        that evaluate to invalid keys do not fail puts/adds, just don't add index entries.
     14        (addData3):
     15        (addData4):
     16        (cursor1Continue3):
     17        (cursor1Continue4):
     18        (cursor2Continue3):
     19        (cursor2Continue4):
     20        (last):
     21        (index1Count):
     22        (index2Count):
     23        * storage/indexeddb/resources/objectstore-basics.js: Remove precondition checks
     24        that would previously raise an exception if invalid keys were specified.
     25        (addAgainFailure):
     26        (testPreConditions.request.onsuccess):
     27        (testPreConditions):
     28
    1292012-05-21  Joshua Bell  <jsbell@chromium.org>
    230
  • trunk/LayoutTests/storage/indexeddb/index-basics-expected.txt

    r117702 r117808  
    4949store.createIndex('indexWhileAddIsInFlight', 'x')
    5050store.createIndex('indexWithWeirdKeyPath', 'foobar')
     51Add data which doesn't have a key in the z index.
    5152event.target.source.add({x: 'value3', y: '456'}, 'key3')
     53Add data which has invalid key for y index, no key for the z index.
     54event.target.source.add({x: 'value4', y: null}, 'key4')
    5255indexObject.getKey('value')
    5356PASS event.target.result is "key"
     
    7982PASS event.target.result.primaryKey is "key3"
    8083event.target.result.continue()
     84PASS event.target.result is non-null.
     85PASS event.target.result.key is "value4"
     86PASS event.target.result.primaryKey is "key4"
     87event.target.result.continue()
    8188PASS event.target.result is null
    8289indexObject.openCursor()
     
    97104PASS event.target.result.value.y is "456"
    98105event.target.result.continue()
     106PASS event.target.result is non-null.
     107PASS event.target.result.key is "value4"
     108PASS event.target.result.value.x is "value4"
     109PASS event.target.result.value.y is null
     110event.target.result.continue()
    99111PASS event.target.result is null
     112request = indexObject.count()
     113PASS event.target.result is 4
     114request = indexObject2.count()
     115PASS event.target.result is 3
     116request = indexObject3.count()
     117PASS event.target.result is 2
    100118Passing an invalid key into indexObject.get({}).
    101119Expecting exception from indexObject.get({})
  • trunk/LayoutTests/storage/indexeddb/index-basics-workers-expected.txt

    r117702 r117808  
    5050[Worker] store.createIndex('indexWhileAddIsInFlight', 'x')
    5151[Worker] store.createIndex('indexWithWeirdKeyPath', 'foobar')
     52[Worker] Add data which doesn't have a key in the z index.
    5253[Worker] event.target.source.add({x: 'value3', y: '456'}, 'key3')
     54[Worker] Add data which has invalid key for y index, no key for the z index.
     55[Worker] event.target.source.add({x: 'value4', y: null}, 'key4')
    5356[Worker] indexObject.getKey('value')
    5457PASS [Worker] event.target.result is "key"
     
    8083PASS [Worker] event.target.result.primaryKey is "key3"
    8184[Worker] event.target.result.continue()
     85PASS [Worker] event.target.result is non-null.
     86PASS [Worker] event.target.result.key is "value4"
     87PASS [Worker] event.target.result.primaryKey is "key4"
     88[Worker] event.target.result.continue()
    8289PASS [Worker] event.target.result is null
    8390[Worker] indexObject.openCursor()
     
    98105PASS [Worker] event.target.result.value.y is "456"
    99106[Worker] event.target.result.continue()
     107PASS [Worker] event.target.result is non-null.
     108PASS [Worker] event.target.result.key is "value4"
     109PASS [Worker] event.target.result.value.x is "value4"
     110PASS [Worker] event.target.result.value.y is null
     111[Worker] event.target.result.continue()
    100112PASS [Worker] event.target.result is null
     113[Worker] request = indexObject.count()
     114PASS [Worker] event.target.result is 4
     115[Worker] request = indexObject2.count()
     116PASS [Worker] event.target.result is 3
     117[Worker] request = indexObject3.count()
     118PASS [Worker] event.target.result is 2
    101119[Worker] Passing an invalid key into indexObject.get({}).
    102120[Worker] Expecting exception from indexObject.get({})
  • trunk/LayoutTests/storage/indexeddb/objectstore-basics-expected.txt

    r117702 r117808  
    105105db.transaction(['storeName'], 'readwrite')
    106106store = transaction.objectStore('storeName')
    107 Expecting exception from store.add({x: null}, 'validkey')
    108 PASS Exception was thrown.
    109 PASS code is IDBDatabaseException.DATA_ERR
     107Ensure invalid key pointed at by index keyPath is ignored
     108store.add({x: null}, 'validkey')
    110109db.transaction(['storeName'], 'readwrite')
    111110store = transaction.objectStore('storeName')
     
    169168PASS Exception was thrown.
    170169PASS code is IDBDatabaseException.DATA_ERR
    171 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.
    172 Expecting exception from storeWithIndex.put({indexKey: null}, 'key')
    173 PASS Exception was thrown.
    174 PASS code is IDBDatabaseException.DATA_ERR
    175170
    176171IDBObjectStore.add()
     
    195190PASS Exception was thrown.
    196191PASS code is IDBDatabaseException.DATA_ERR
    197 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.
    198 Expecting exception from storeWithIndex.add({indexKey: null}, 'key')
    199 PASS Exception was thrown.
    200 PASS code is IDBDatabaseException.DATA_ERR
    201192PASS successfullyParsed is true
    202193
  • trunk/LayoutTests/storage/indexeddb/objectstore-basics-workers-expected.txt

    r117702 r117808  
    106106[Worker] db.transaction(['storeName'], 'readwrite')
    107107[Worker] store = transaction.objectStore('storeName')
    108 [Worker] Expecting exception from store.add({x: null}, 'validkey')
    109 PASS [Worker] Exception was thrown.
    110 PASS [Worker] code is IDBDatabaseException.DATA_ERR
     108[Worker] Ensure invalid key pointed at by index keyPath is ignored
     109[Worker] store.add({x: null}, 'validkey')
    111110[Worker] db.transaction(['storeName'], 'readwrite')
    112111[Worker] store = transaction.objectStore('storeName')
     
    170169PASS [Worker] Exception was thrown.
    171170PASS [Worker] code is IDBDatabaseException.DATA_ERR
    172 [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.
    173 [Worker] Expecting exception from storeWithIndex.put({indexKey: null}, 'key')
    174 PASS [Worker] Exception was thrown.
    175 PASS [Worker] code is IDBDatabaseException.DATA_ERR
    176171[Worker]
    177172[Worker] IDBObjectStore.add()
     
    196191PASS [Worker] Exception was thrown.
    197192PASS [Worker] code is IDBDatabaseException.DATA_ERR
    198 [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.
    199 [Worker] Expecting exception from storeWithIndex.add({indexKey: null}, 'key')
    200 PASS [Worker] Exception was thrown.
    201 PASS [Worker] code is IDBDatabaseException.DATA_ERR
    202193PASS successfullyParsed is true
    203194
  • trunk/LayoutTests/storage/indexeddb/resources/index-basics.js

    r117702 r117808  
    8686{
    8787    event = evt;
    88     // Add data which doesn't have a key in the zIndex.
     88    debug("Add data which doesn't have a key in the z index.");
    8989    request = evalAndLog("event.target.source.add({x: 'value3', y: '456'}, 'key3')");
     90    request.onsuccess = addData4;
     91    request.onerror = unexpectedErrorCallback;
     92}
     93
     94function addData4(evt)
     95{
     96    event = evt;
     97    debug("Add data which has invalid key for y index, no key for the z index.");
     98    request = evalAndLog("event.target.source.add({x: 'value4', y: null}, 'key4')");
    9099    request.onsuccess = getData;
    91100    request.onerror = unexpectedErrorCallback;
     
    205214    // We re-use the last request object.
    206215    evalAndLog("event.target.result.continue()");
     216    self.request.onsuccess = cursor1Continue4;
     217}
     218
     219function cursor1Continue4(evt)
     220{
     221    event = evt;
     222    shouldBeNonNull("event.target.result");
     223    shouldBeEqualToString("event.target.result.key", "value4");
     224    shouldBeEqualToString("event.target.result.primaryKey", "key4");
     225
     226    // We re-use the last request object.
     227    evalAndLog("event.target.result.continue()");
    207228    self.request.onsuccess = openObjectCursor;
    208229}
     
    255276    // We re-use the last request object.
    256277    evalAndLog("event.target.result.continue()");
     278    self.request.onsuccess = cursor2Continue4;
     279}
     280
     281function cursor2Continue4(evt)
     282{
     283    event = evt;
     284    shouldBeNonNull("event.target.result");
     285    shouldBeEqualToString("event.target.result.key", "value4");
     286    shouldBeEqualToString("event.target.result.value.x", "value4");
     287    shouldBe("event.target.result.value.y", "null");
     288
     289    // We re-use the last request object.
     290    evalAndLog("event.target.result.continue()");
    257291    self.request.onsuccess = last;
    258292}
     
    262296    event = evt;
    263297    shouldBeNull("event.target.result");
     298
     299    evalAndLog("request = indexObject.count()");
     300    request.onerror = unexpectedErrorCallback;
     301    request.onsuccess = index1Count;
     302}
     303
     304function index1Count(evt)
     305{
     306    event = evt;
     307    shouldBe("event.target.result", "4");
     308
     309    evalAndLog("request = indexObject2.count()");
     310    request.onerror = unexpectedErrorCallback;
     311    request.onsuccess = index2Count;
     312}
     313
     314function index2Count(evt)
     315{
     316    event = evt;
     317    shouldBe("event.target.result", "3");
     318
     319    evalAndLog("request = indexObject3.count()");
     320    request.onerror = unexpectedErrorCallback;
     321    request.onsuccess = index3Count;
     322}
     323
     324function index3Count(evt)
     325{
     326    event = evt;
     327    shouldBe("event.target.result", "2");
    264328
    265329    debug("Passing an invalid key into indexObject.get({}).");
  • trunk/LayoutTests/storage/indexeddb/resources/objectstore-basics.js

    r117702 r117808  
    191191    store = evalAndLog("store = transaction.objectStore('storeName')");
    192192
    193     evalAndExpectException("store.add({x: null}, 'validkey')", "IDBDatabaseException.DATA_ERR");
     193    debug("Ensure invalid key pointed at by index keyPath is ignored");
     194    evalAndLog("store.add({x: null}, 'validkey')");
    194195
    195196    transaction = evalAndLog("db.transaction(['storeName'], 'readwrite')");
     
    287288        evalAndExpectException("storeWithOutOfLineKeys.put({}, null)", "IDBDatabaseException.DATA_ERR");
    288289
    289         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.");
    290         evalAndExpectException("storeWithIndex.put({indexKey: null}, 'key')", "IDBDatabaseException.DATA_ERR");
    291 
    292290        debug("");
    293291        debug("IDBObjectStore.add()");
     
    307305        evalAndExpectException("storeWithOutOfLineKeys.add({}, null)", "IDBDatabaseException.DATA_ERR");
    308306
    309         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.");
    310         evalAndExpectException("storeWithIndex.add({indexKey: null}, 'key')", "IDBDatabaseException.DATA_ERR");
    311 
    312307        finishJSTest();
    313308    };
  • trunk/Source/WebCore/ChangeLog

    r117799 r117808  
     12012-05-21  Joshua Bell  <jsbell@chromium.org>
     2
     3        IndexedDB: Index key paths that yield invalid keys should not fail an add/put
     4        https://bugs.webkit.org/show_bug.cgi?id=86122
     5
     6        Reviewed by Tony Chang.
     7
     8        A clause was removed from the IDB spec. Previously, on add/put, if evaluating an
     9        index's key path yielded a value that was not a valid key, an exception would be
     10        raised. Now, it is treated the same as if no value was yielded.
     11
     12        Test: storage/indexeddb/index-basics.html
     13        Test: storage/indexeddb/index-basics-workers.html
     14        Test: storage/indexeddb/objectstore-basics.html
     15        Test: storage/indexeddb/objectstore-basics-workers.html
     16
     17        * Modules/indexeddb/IDBObjectStoreBackendImpl.cpp:
     18        (WebCore::IDBObjectStoreBackendImpl::put): Preconditions removed
     19        (WebCore::IDBObjectStoreBackendImpl::putInternal): Treat invalid keys the same as missing keys.
     20
    1212012-05-21  Pavel Feldman  <pfeldman@chromium.org>
    222
  • trunk/Source/WebCore/Modules/indexeddb/IDBObjectStoreBackendImpl.cpp

    r117512 r117808  
    206206            return;
    207207        }
    208         for (IndexMap::iterator it = m_indexes.begin(); it != m_indexes.end(); ++it) {
    209             const RefPtr<IDBIndexBackendImpl>& index = it->second;
    210             RefPtr<IDBKey> indexKey = fetchKeyFromKeyPath(value.get(), index->keyPath());
    211             if (indexKey && !indexKey->isValid()) {
    212                 ec = IDBDatabaseException::DATA_ERR;
    213                 return;
    214             }
    215         }
    216208    } else {
    217209        ASSERT(key);
     
    294286
    295287        RefPtr<IDBKey> indexKey = fetchKeyFromKeyPath(value.get(), index->keyPath());
    296         if (!indexKey) {
    297             indexKeys.append(indexKey.release());
     288        if (!indexKey || !indexKey->isValid()) {
     289            // Null/invalid keys not added to index; null entry keeps iterator/vector indexes consistent.
     290            indexKey.clear();
     291            indexKeys.append(indexKey);
    298292            continue;
    299293        }
Note: See TracChangeset for help on using the changeset viewer.