Changeset 115902 in webkit


Ignore:
Timestamp:
May 2, 2012, 4:03:42 PM (13 years ago)
Author:
jsbell@chromium.org
Message:

IndexedDB: Handle generated keys up to 253
https://bugs.webkit.org/show_bug.cgi?id=85114

Source/WebCore:

The spec defines the behavior for generated keys up to 253
(the maximum integer storable as an ECMAScript number) and
the error case when going beyond that. Ensure that we can
handle values up to that point and generate errors beyond.

Reviewed by Tony Chang.

Test: storage/indexeddb/key-generator.html

  • Modules/indexeddb/IDBBackingStore.h:

(IDBBackingStore):

  • Modules/indexeddb/IDBLevelDBBackingStore.cpp:

(WebCore::IDBLevelDBBackingStore::nextAutoIncrementNumber):

  • Modules/indexeddb/IDBLevelDBBackingStore.h:

(IDBLevelDBBackingStore):

  • Modules/indexeddb/IDBObjectStoreBackendImpl.cpp:

(WebCore::IDBObjectStoreBackendImpl::putInternal):
(WebCore::IDBObjectStoreBackendImpl::genAutoIncrementKey):

  • Modules/indexeddb/IDBObjectStoreBackendImpl.h:

(IDBObjectStoreBackendImpl):

LayoutTests:

Reviewed by Tony Chang.

  • storage/indexeddb/key-generator-expected.txt:
  • storage/indexeddb/resources/key-generator.js:

(get defineTest):

Location:
trunk
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r115901 r115902  
     12012-05-02  Joshua Bell  <jsbell@chromium.org>
     2
     3        IndexedDB: Handle generated keys up to 2^53
     4        https://bugs.webkit.org/show_bug.cgi?id=85114
     5
     6        Reviewed by Tony Chang.
     7
     8        * storage/indexeddb/key-generator-expected.txt:
     9        * storage/indexeddb/resources/key-generator.js:
     10        (get defineTest):
     11
    1122012-05-02  Zhenyao Mo  <zmo@google.com>
    213
  • trunk/LayoutTests/storage/indexeddb/key-generator-expected.txt

    r112490 r115902  
    143143PASS Got "d" for key: 2
    144144db.close()
     145
     146Verify that keys above 2^53 result in errors.
     147request = indexedDB.deleteDatabase('key-generator')
     148request = indexedDB.open('key-generator')
     149db = request.result
     150request = db.setVersion('1')
     151trans = request.result
     152trans1 = db.transaction(['store'], IDBTransaction.READ_WRITE)
     153store_t1 = trans1.objectStore('store')
     154store_t1.put('a')
     155request = store.get(1)
     156store_t1.put('b', 9007199254740992)
     157request = store.get(9007199254740992)
     158store_t1.put('c')
     159store_t1.put('d', 2)
     160request = store.get(2)
     161PASS Got "a" for key: 1
     162PASS Got "b" for key: 9007199254740992
     163Error event fired auto-incrementing past 2^53 (as expected)
     164PASS event.target.errorCode is IDBDatabaseException.DATA_ERR
     165event.preventDefault()
     166PASS Got "d" for key: 2
     167db.close()
    145168PASS successfullyParsed is true
    146169
  • trunk/LayoutTests/storage/indexeddb/resources/key-generator.js

    r112202 r115902  
    204204);
    205205
     206defineTest(
     207    'Verify that keys above 2^53 result in errors.',
     208    function (db, trans) {
     209        db.createObjectStore('store', { autoIncrement: true });
     210    },
     211
     212    function (db, callback) {
     213        evalAndLog("trans1 = db.transaction(['store'], IDBTransaction.READ_WRITE)");
     214        evalAndLog("store_t1 = trans1.objectStore('store')");
     215        evalAndLog("store_t1.put('a')");
     216        check(store_t1, 1, 'a');
     217        evalAndLog("store_t1.put('b', 9007199254740992)");
     218        check(store_t1, 9007199254740992, 'b');
     219        request = evalAndLog("store_t1.put('c')");
     220        request.onsuccess = unexpectedSuccessCallback;
     221        request.onerror = function () {
     222            debug("Error event fired auto-incrementing past 2^53 (as expected)");
     223            shouldBe("event.target.errorCode", "IDBDatabaseException.DATA_ERR");
     224            evalAndLog("event.preventDefault()");
     225        };
     226        evalAndLog("store_t1.put('d', 2)");
     227        check(store_t1, 2, 'd');
     228
     229        trans1.oncomplete = callback;
     230    }
     231);
     232
    206233test();
  • trunk/Source/WebCore/ChangeLog

    r115897 r115902  
     12012-05-02  Joshua Bell  <jsbell@chromium.org>
     2
     3        IndexedDB: Handle generated keys up to 2^53
     4        https://bugs.webkit.org/show_bug.cgi?id=85114
     5
     6        The spec defines the behavior for generated keys up to 2^53
     7        (the maximum integer storable as an ECMAScript number) and
     8        the error case when going beyond that. Ensure that we can
     9        handle values up to that point and generate errors beyond.
     10
     11        Reviewed by Tony Chang.
     12
     13        Test: storage/indexeddb/key-generator.html
     14
     15        * Modules/indexeddb/IDBBackingStore.h:
     16        (IDBBackingStore):
     17        * Modules/indexeddb/IDBLevelDBBackingStore.cpp:
     18        (WebCore::IDBLevelDBBackingStore::nextAutoIncrementNumber):
     19        * Modules/indexeddb/IDBLevelDBBackingStore.h:
     20        (IDBLevelDBBackingStore):
     21        * Modules/indexeddb/IDBObjectStoreBackendImpl.cpp:
     22        (WebCore::IDBObjectStoreBackendImpl::putInternal):
     23        (WebCore::IDBObjectStoreBackendImpl::genAutoIncrementKey):
     24        * Modules/indexeddb/IDBObjectStoreBackendImpl.h:
     25        (IDBObjectStoreBackendImpl):
     26
    1272012-05-02  Adam Klein  <adamk@chromium.org>
    228
  • trunk/Source/WebCore/Modules/indexeddb/IDBBackingStore.h

    r115282 r115902  
    6868    virtual void clearObjectStore(int64_t databaseId, int64_t objectStoreId) = 0;
    6969    virtual void deleteObjectStoreRecord(int64_t databaseId, int64_t objectStoreId, const ObjectStoreRecordIdentifier*) = 0;
    70     virtual double nextAutoIncrementNumber(int64_t databaseId, int64_t objectStoreId) = 0;
     70    virtual int64_t nextAutoIncrementNumber(int64_t databaseId, int64_t objectStoreId) = 0;
    7171    virtual bool keyExistsInObjectStore(int64_t databaseId, int64_t objectStoreId, const IDBKey&, ObjectStoreRecordIdentifier* foundRecordIdentifier) = 0;
    7272
  • trunk/Source/WebCore/Modules/indexeddb/IDBLevelDBBackingStore.cpp

    r115743 r115902  
    603603}
    604604
    605 double IDBLevelDBBackingStore::nextAutoIncrementNumber(int64_t databaseId, int64_t objectStoreId)
     605int64_t IDBLevelDBBackingStore::nextAutoIncrementNumber(int64_t databaseId, int64_t objectStoreId)
    606606{
    607607    ASSERT(m_currentTransaction);
     
    611611    OwnPtr<LevelDBIterator> it = m_currentTransaction->createIterator();
    612612
    613     int maxNumericKey = 0;
    614 
    615     // FIXME: Be more efficient: seek to something after the object store data, then reverse.
     613    int64_t maxNumericKey = 0;
     614
     615    // FIXME: This does a forward scan over all keys. Improve it.
     616    // Since all dates > all numbers, create Date(-Infinity) and seek backwards.
    616617
    617618    for (it->seek(startKey); it->isValid() && compareKeys(it->key(), stopKey) < 0; it->next()) {
  • trunk/Source/WebCore/Modules/indexeddb/IDBLevelDBBackingStore.h

    r109493 r115902  
    5959    virtual void clearObjectStore(int64_t databaseId, int64_t objectStoreId);
    6060    virtual void deleteObjectStoreRecord(int64_t databaseId, int64_t objectStoreId, const ObjectStoreRecordIdentifier*);
    61     virtual double nextAutoIncrementNumber(int64_t databaseId, int64_t objectStoreId);
     61    virtual int64_t nextAutoIncrementNumber(int64_t databaseId, int64_t objectStoreId);
    6262    virtual bool keyExistsInObjectStore(int64_t databaseId, int64_t objectStoreId, const IDBKey&, ObjectStoreRecordIdentifier* foundRecordIdentifier);
    6363
  • trunk/Source/WebCore/Modules/indexeddb/IDBObjectStoreBackendImpl.cpp

    r114805 r115902  
    256256            if (!key) {
    257257                RefPtr<IDBKey> autoIncKey = objectStore->genAutoIncrementKey();
     258                if (!autoIncKey->valid()) {
     259                    callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::DATA_ERR, "Maximum key generator value reached."));
     260                    return;
     261                }
    258262                if (hasKeyPath) {
    259263                    RefPtr<SerializedScriptValue> valueAfterInjection = injectKeyIntoKeyPath(autoIncKey, value, objectStore->m_keyPath);
     
    680684PassRefPtr<IDBKey> IDBObjectStoreBackendImpl::genAutoIncrementKey()
    681685{
     686    const int64_t kMaxGeneratorValue = 9007199254740992; // Maximum integer storable as ECMAScript number.
     687    if (m_autoIncrementNumber > kMaxGeneratorValue)
     688        return IDBKey::createInvalid();
    682689    if (m_autoIncrementNumber > 0)
    683690        return IDBKey::createNumber(m_autoIncrementNumber++);
    684691
    685     m_autoIncrementNumber = static_cast<int>(m_backingStore->nextAutoIncrementNumber(m_databaseId, id()));
     692    m_autoIncrementNumber = m_backingStore->nextAutoIncrementNumber(m_databaseId, id());
     693    if (m_autoIncrementNumber > kMaxGeneratorValue)
     694        return IDBKey::createInvalid();
    686695    return IDBKey::createNumber(m_autoIncrementNumber++);
    687696}
  • trunk/Source/WebCore/Modules/indexeddb/IDBObjectStoreBackendImpl.h

    r114805 r115902  
    116116    typedef HashMap<String, RefPtr<IDBIndexBackendImpl> > IndexMap;
    117117    IndexMap m_indexes;
    118     int m_autoIncrementNumber;
     118    int64_t m_autoIncrementNumber;
    119119};
    120120
Note: See TracChangeset for help on using the changeset viewer.