Changeset 136958 in webkit


Ignore:
Timestamp:
Dec 7, 2012, 9:52:36 AM (12 years ago)
Author:
jsbell@chromium.org
Message:

IndexedDB: Check SSV version when opening database
https://bugs.webkit.org/show_bug.cgi?id=102243

Reviewed by Tony Chang.

Ensure that the data format (SerializedScriptValue) isn't "from the future" when opening
a backing store. Treat an unknown version the same as an unknown schema version.

Chromium-side test at https://codereview.chromium.org/11470013/ (same as other schema version tests)

  • Modules/indexeddb/IDBBackingStore.cpp:

(WebCore):
(WebCore::isSchemaKnown): Check data version as well.
(WebCore::setUpMetadata): Ensure data version is recorded; bump schema version.

  • Modules/indexeddb/IDBLevelDBCoding.cpp: Encoding for "DataVersion" global metadata entry.

(IDBLevelDBCoding):
(WebCore::IDBLevelDBCoding::compare):
(WebCore::IDBLevelDBCoding::DataVersionKey::encode):

  • Modules/indexeddb/IDBLevelDBCoding.h:

(DataVersionKey):
(IDBLevelDBCoding):

  • bindings/js/SerializedScriptValue.cpp:

(SerializedScriptValue::wireFormatVersion): New method (JSC side).

  • bindings/js/SerializedScriptValue.h:
  • bindings/v8/SerializedScriptValue.cpp:

(WebCore::SerializedScriptValue::wireFormatVersion): New method (V8 side).
(WebCore):

  • bindings/v8/SerializedScriptValue.h:

(SerializedScriptValue):

Location:
trunk/Source/WebCore
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r136956 r136958  
     12012-12-07  Joshua Bell  <jsbell@chromium.org>
     2
     3        IndexedDB: Check SSV version when opening database
     4        https://bugs.webkit.org/show_bug.cgi?id=102243
     5
     6        Reviewed by Tony Chang.
     7
     8        Ensure that the data format (SerializedScriptValue) isn't "from the future" when opening
     9        a backing store. Treat an unknown version the same as an unknown schema version.
     10
     11        Chromium-side test at https://codereview.chromium.org/11470013/ (same as other schema version tests)
     12
     13        * Modules/indexeddb/IDBBackingStore.cpp:
     14        (WebCore):
     15        (WebCore::isSchemaKnown): Check data version as well.
     16        (WebCore::setUpMetadata): Ensure data version is recorded; bump schema version.
     17        * Modules/indexeddb/IDBLevelDBCoding.cpp: Encoding for "DataVersion" global metadata entry.
     18        (IDBLevelDBCoding):
     19        (WebCore::IDBLevelDBCoding::compare):
     20        (WebCore::IDBLevelDBCoding::DataVersionKey::encode):
     21        * Modules/indexeddb/IDBLevelDBCoding.h:
     22        (DataVersionKey):
     23        (IDBLevelDBCoding):
     24        * bindings/js/SerializedScriptValue.cpp:
     25        (SerializedScriptValue::wireFormatVersion): New method (JSC side).
     26        * bindings/js/SerializedScriptValue.h:
     27        * bindings/v8/SerializedScriptValue.cpp:
     28        (WebCore::SerializedScriptValue::wireFormatVersion): New method (V8 side).
     29        (WebCore):
     30        * bindings/v8/SerializedScriptValue.h:
     31        (SerializedScriptValue):
     32
    1332012-12-07  Andreas Kling  <akling@apple.com>
    234
  • trunk/Source/WebCore/Modules/indexeddb/IDBBackingStore.cpp

    r136897 r136958  
    182182};
    183183
    184 const int64_t latestSchemaVersion = 1;
     184// 0 - Initial version.
     185// 1 - Adds UserIntVersion to DatabaseMetaData.
     186// 2 - Adds DataVersion to to global metadata.
     187const int64_t latestKnownSchemaVersion = 2;
    185188static bool isSchemaKnown(LevelDBDatabase* db)
    186189{
    187     int64_t schemaVersion = 0;
    188     const Vector<char> metaDataKey = SchemaVersionKey::encode();
    189     if (!getInt(db, metaDataKey, schemaVersion))
     190    int64_t dbSchemaVersion = 0;
     191    if (!getInt(db, SchemaVersionKey::encode(), dbSchemaVersion))
    190192        return true;
    191     return schemaVersion <= latestSchemaVersion;
     193    if (dbSchemaVersion > latestKnownSchemaVersion)
     194        return false;
     195
     196    const uint32_t latestKnownDataVersion = SerializedScriptValue::wireFormatVersion();
     197    int64_t dbDataVersion = 0;
     198    if (!getInt(db, DataVersionKey::encode(), dbDataVersion))
     199        return true;
     200
     201    if (dbDataVersion > latestKnownDataVersion)
     202        return false;
     203
     204    return true;
    192205}
    193206
    194207static bool setUpMetadata(LevelDBDatabase* db, const String& origin)
    195208{
    196     const Vector<char> metaDataKey = SchemaVersionKey::encode();
     209    const uint32_t latestKnownDataVersion = SerializedScriptValue::wireFormatVersion();
     210    const Vector<char> schemaVersionKey = SchemaVersionKey::encode();
     211    const Vector<char> dataVersionKey = DataVersionKey::encode();
     212
    197213    RefPtr<LevelDBTransaction> transaction = LevelDBTransaction::create(db);
    198214
    199     int64_t schemaVersion = 0;
    200     if (!getInt(transaction.get(), metaDataKey, schemaVersion)) {
    201         schemaVersion = latestSchemaVersion;
    202         putInt(transaction.get(), metaDataKey, latestSchemaVersion);
     215    int64_t dbSchemaVersion = 0;
     216    int64_t dbDataVersion = 0;
     217    if (!getInt(transaction.get(), schemaVersionKey, dbSchemaVersion)) {
     218        // Initialize new backing store.
     219        dbSchemaVersion = latestKnownSchemaVersion;
     220        putInt(transaction.get(), schemaVersionKey, dbSchemaVersion);
     221        dbDataVersion = latestKnownDataVersion;
     222        putInt(transaction.get(), dataVersionKey, dbDataVersion);
    203223    } else {
    204         ASSERT(schemaVersion <= latestSchemaVersion);
    205         if (!schemaVersion) {
    206             schemaVersion = latestSchemaVersion;
    207             putInt(transaction.get(), metaDataKey, schemaVersion);
     224        // Upgrade old backing store.
     225        ASSERT(dbSchemaVersion <= latestKnownSchemaVersion);
     226        if (dbSchemaVersion < 1) {
     227            dbSchemaVersion = 1;
     228            putInt(transaction.get(), schemaVersionKey, dbSchemaVersion);
    208229            const Vector<char> startKey = DatabaseNameKey::encodeMinKeyForOrigin(origin);
    209230            const Vector<char> stopKey = DatabaseNameKey::encodeStopKeyForOrigin(origin);
     
    219240            }
    220241        }
    221     }
    222 
    223     ASSERT(schemaVersion == latestSchemaVersion);
     242        if (dbSchemaVersion < 2) {
     243            dbSchemaVersion = 2;
     244            putInt(transaction.get(), schemaVersionKey, dbSchemaVersion);
     245            dbDataVersion = SerializedScriptValue::wireFormatVersion();
     246            putInt(transaction.get(), dataVersionKey, dbDataVersion);
     247        }
     248    }
     249
     250    // All new values will be written using this serialization version.
     251    if (!getInt(transaction.get(), dataVersionKey, dbDataVersion)) {
     252        InternalError(IDBLevelDBBackingStoreReadError);
     253        return false;
     254    }
     255    if (dbDataVersion < latestKnownDataVersion) {
     256        dbDataVersion = latestKnownDataVersion;
     257        putInt(transaction.get(), dataVersionKey, dbDataVersion);
     258    }
     259
     260    ASSERT(dbSchemaVersion == latestKnownSchemaVersion);
     261    ASSERT(dbDataVersion == latestKnownDataVersion);
     262
    224263    if (!transaction->commit()) {
    225264        InternalError(IDBLevelDBBackingStoreWriteError);
  • trunk/Source/WebCore/Modules/indexeddb/IDBLevelDBCoding.cpp

    r134680 r136958  
    4848// Global meta-data have keys with prefix (0,0,0), followed by a type byte:
    4949//
    50 //     <0, 0, 0, 0>                                           => IndexedDB/LevelDB schema version (0 for now) [SchemaVersionKey]
     50//     <0, 0, 0, 0>                                           => IndexedDB/LevelDB schema version [SchemaVersionKey]
    5151//     <0, 0, 0, 1>                                           => The maximum database id ever allocated [MaxDatabaseIdKey]
     52//     <0, 0, 0, 2>                                           => SerializedScriptValue version [DataVersionKey]
    5253//     <0, 0, 0, 100, database id>                            => Existence implies the database id is in the free list [DatabaseFreeListKey]
    5354//     <0, 0, 0, 201, utf16 origin name, utf16 database name> => Database id [DatabaseNameKey]
     
    155156static const unsigned char SchemaVersionTypeByte = 0;
    156157static const unsigned char MaxDatabaseIdTypeByte = 1;
    157 static const unsigned char MaxSimpleGlobalMetaDataTypeByte = 2; // Insert before this and increment.
     158static const unsigned char DataVersionTypeByte = 2;
     159static const unsigned char MaxSimpleGlobalMetaDataTypeByte = 3; // Insert before this and increment.
    158160static const unsigned char DatabaseFreeListTypeByte = 100;
    159161static const unsigned char DatabaseNameTypeByte = 201;
     
    10481050}
    10491051
     1052Vector<char> DataVersionKey::encode()
     1053{
     1054    KeyPrefix prefix(0, 0, 0);
     1055    Vector<char> ret = prefix.encode();
     1056    ret.append(encodeByte(DataVersionTypeByte));
     1057    return ret;
     1058}
     1059
    10501060DatabaseFreeListKey::DatabaseFreeListKey()
    10511061    : m_databaseId(-1)
  • trunk/Source/WebCore/Modules/indexeddb/IDBLevelDBCoding.h

    r134680 r136958  
    112112};
    113113
     114class DataVersionKey {
     115public:
     116    static Vector<char> encode();
     117};
     118
    114119class DatabaseFreeListKey {
    115120public:
  • trunk/Source/WebCore/bindings/js/SerializedScriptValue.cpp

    r136097 r136958  
    19861986}
    19871987
    1988 }
     1988uint32_t SerializedScriptValue::wireFormatVersion()
     1989{
     1990    return CurrentVersion;
     1991}
     1992
     1993}
  • trunk/Source/WebCore/bindings/js/SerializedScriptValue.h

    r136097 r136958  
    8484    static PassRefPtr<SerializedScriptValue> booleanValue(bool value);
    8585
     86    static uint32_t wireFormatVersion();
     87
    8688    String toString();
    8789   
  • trunk/Source/WebCore/bindings/v8/SerializedScriptValue.cpp

    r136634 r136958  
    24502450}
    24512451
     2452uint32_t SerializedScriptValue::wireFormatVersion()
     2453{
     2454    return WebCore::wireFormatVersion;
     2455}
     2456
    24522457} // namespace WebCore
  • trunk/Source/WebCore/bindings/v8/SerializedScriptValue.h

    r123269 r136958  
    6666    static PassRefPtr<SerializedScriptValue> numberValue(double value, v8::Isolate* = 0);
    6767
     68    static uint32_t wireFormatVersion();
     69
    6870    PassRefPtr<SerializedScriptValue> release();
    6971
Note: See TracChangeset for help on using the changeset viewer.