Title: [136958] trunk/Source/WebCore
Revision
136958
Author
jsb...@chromium.org
Date
2012-12-07 09:52:36 -0800 (Fri, 07 Dec 2012)

Log 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):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (136957 => 136958)


--- trunk/Source/WebCore/ChangeLog	2012-12-07 16:54:31 UTC (rev 136957)
+++ trunk/Source/WebCore/ChangeLog	2012-12-07 17:52:36 UTC (rev 136958)
@@ -1,3 +1,35 @@
+2012-12-07  Joshua Bell  <jsb...@chromium.org>
+
+        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):
+
 2012-12-07  Andreas Kling  <akl...@apple.com>
 
         Throw away StyleResolvers that haven't been used for a long time.

Modified: trunk/Source/WebCore/Modules/indexeddb/IDBBackingStore.cpp (136957 => 136958)


--- trunk/Source/WebCore/Modules/indexeddb/IDBBackingStore.cpp	2012-12-07 16:54:31 UTC (rev 136957)
+++ trunk/Source/WebCore/Modules/indexeddb/IDBBackingStore.cpp	2012-12-07 17:52:36 UTC (rev 136958)
@@ -181,30 +181,51 @@
     virtual const char* name() const { return "idb_cmp1"; }
 };
 
-const int64_t latestSchemaVersion = 1;
+// 0 - Initial version.
+// 1 - Adds UserIntVersion to DatabaseMetaData.
+// 2 - Adds DataVersion to to global metadata.
+const int64_t latestKnownSchemaVersion = 2;
 static bool isSchemaKnown(LevelDBDatabase* db)
 {
-    int64_t schemaVersion = 0;
-    const Vector<char> metaDataKey = SchemaVersionKey::encode();
-    if (!getInt(db, metaDataKey, schemaVersion))
+    int64_t dbSchemaVersion = 0;
+    if (!getInt(db, SchemaVersionKey::encode(), dbSchemaVersion))
         return true;
-    return schemaVersion <= latestSchemaVersion;
+    if (dbSchemaVersion > latestKnownSchemaVersion)
+        return false;
+
+    const uint32_t latestKnownDataVersion = SerializedScriptValue::wireFormatVersion();
+    int64_t dbDataVersion = 0;
+    if (!getInt(db, DataVersionKey::encode(), dbDataVersion))
+        return true;
+
+    if (dbDataVersion > latestKnownDataVersion)
+        return false;
+
+    return true;
 }
 
 static bool setUpMetadata(LevelDBDatabase* db, const String& origin)
 {
-    const Vector<char> metaDataKey = SchemaVersionKey::encode();
+    const uint32_t latestKnownDataVersion = SerializedScriptValue::wireFormatVersion();
+    const Vector<char> schemaVersionKey = SchemaVersionKey::encode();
+    const Vector<char> dataVersionKey = DataVersionKey::encode();
+
     RefPtr<LevelDBTransaction> transaction = LevelDBTransaction::create(db);
 
-    int64_t schemaVersion = 0;
-    if (!getInt(transaction.get(), metaDataKey, schemaVersion)) {
-        schemaVersion = latestSchemaVersion;
-        putInt(transaction.get(), metaDataKey, latestSchemaVersion);
+    int64_t dbSchemaVersion = 0;
+    int64_t dbDataVersion = 0;
+    if (!getInt(transaction.get(), schemaVersionKey, dbSchemaVersion)) {
+        // Initialize new backing store.
+        dbSchemaVersion = latestKnownSchemaVersion;
+        putInt(transaction.get(), schemaVersionKey, dbSchemaVersion);
+        dbDataVersion = latestKnownDataVersion;
+        putInt(transaction.get(), dataVersionKey, dbDataVersion);
     } else {
-        ASSERT(schemaVersion <= latestSchemaVersion);
-        if (!schemaVersion) {
-            schemaVersion = latestSchemaVersion;
-            putInt(transaction.get(), metaDataKey, schemaVersion);
+        // Upgrade old backing store.
+        ASSERT(dbSchemaVersion <= latestKnownSchemaVersion);
+        if (dbSchemaVersion < 1) {
+            dbSchemaVersion = 1;
+            putInt(transaction.get(), schemaVersionKey, dbSchemaVersion);
             const Vector<char> startKey = DatabaseNameKey::encodeMinKeyForOrigin(origin);
             const Vector<char> stopKey = DatabaseNameKey::encodeStopKeyForOrigin(origin);
             OwnPtr<LevelDBIterator> it = db->createIterator();
@@ -218,9 +239,27 @@
                 putVarInt(transaction.get(), intVersionKey, IDBDatabaseMetadata::DefaultIntVersion);
             }
         }
+        if (dbSchemaVersion < 2) {
+            dbSchemaVersion = 2;
+            putInt(transaction.get(), schemaVersionKey, dbSchemaVersion);
+            dbDataVersion = SerializedScriptValue::wireFormatVersion();
+            putInt(transaction.get(), dataVersionKey, dbDataVersion);
+        }
     }
 
-    ASSERT(schemaVersion == latestSchemaVersion);
+    // All new values will be written using this serialization version.
+    if (!getInt(transaction.get(), dataVersionKey, dbDataVersion)) {
+        InternalError(IDBLevelDBBackingStoreReadError);
+        return false;
+    }
+    if (dbDataVersion < latestKnownDataVersion) {
+        dbDataVersion = latestKnownDataVersion;
+        putInt(transaction.get(), dataVersionKey, dbDataVersion);
+    }
+
+    ASSERT(dbSchemaVersion == latestKnownSchemaVersion);
+    ASSERT(dbDataVersion == latestKnownDataVersion);
+
     if (!transaction->commit()) {
         InternalError(IDBLevelDBBackingStoreWriteError);
         return false;

Modified: trunk/Source/WebCore/Modules/indexeddb/IDBLevelDBCoding.cpp (136957 => 136958)


--- trunk/Source/WebCore/Modules/indexeddb/IDBLevelDBCoding.cpp	2012-12-07 16:54:31 UTC (rev 136957)
+++ trunk/Source/WebCore/Modules/indexeddb/IDBLevelDBCoding.cpp	2012-12-07 17:52:36 UTC (rev 136958)
@@ -47,8 +47,9 @@
 //
 // Global meta-data have keys with prefix (0,0,0), followed by a type byte:
 //
-//     <0, 0, 0, 0>                                           => IndexedDB/LevelDB schema version (0 for now) [SchemaVersionKey]
+//     <0, 0, 0, 0>                                           => IndexedDB/LevelDB schema version [SchemaVersionKey]
 //     <0, 0, 0, 1>                                           => The maximum database id ever allocated [MaxDatabaseIdKey]
+//     <0, 0, 0, 2>                                           => SerializedScriptValue version [DataVersionKey]
 //     <0, 0, 0, 100, database id>                            => Existence implies the database id is in the free list [DatabaseFreeListKey]
 //     <0, 0, 0, 201, utf16 origin name, utf16 database name> => Database id [DatabaseNameKey]
 //
@@ -154,7 +155,8 @@
 
 static const unsigned char SchemaVersionTypeByte = 0;
 static const unsigned char MaxDatabaseIdTypeByte = 1;
-static const unsigned char MaxSimpleGlobalMetaDataTypeByte = 2; // Insert before this and increment.
+static const unsigned char DataVersionTypeByte = 2;
+static const unsigned char MaxSimpleGlobalMetaDataTypeByte = 3; // Insert before this and increment.
 static const unsigned char DatabaseFreeListTypeByte = 100;
 static const unsigned char DatabaseNameTypeByte = 201;
 
@@ -1047,6 +1049,14 @@
     return ret;
 }
 
+Vector<char> DataVersionKey::encode()
+{
+    KeyPrefix prefix(0, 0, 0);
+    Vector<char> ret = prefix.encode();
+    ret.append(encodeByte(DataVersionTypeByte));
+    return ret;
+}
+
 DatabaseFreeListKey::DatabaseFreeListKey()
     : m_databaseId(-1)
 {

Modified: trunk/Source/WebCore/Modules/indexeddb/IDBLevelDBCoding.h (136957 => 136958)


--- trunk/Source/WebCore/Modules/indexeddb/IDBLevelDBCoding.h	2012-12-07 16:54:31 UTC (rev 136957)
+++ trunk/Source/WebCore/Modules/indexeddb/IDBLevelDBCoding.h	2012-12-07 17:52:36 UTC (rev 136958)
@@ -111,6 +111,11 @@
     static Vector<char> encode();
 };
 
+class DataVersionKey {
+public:
+    static Vector<char> encode();
+};
+
 class DatabaseFreeListKey {
 public:
     DatabaseFreeListKey();

Modified: trunk/Source/WebCore/bindings/js/SerializedScriptValue.cpp (136957 => 136958)


--- trunk/Source/WebCore/bindings/js/SerializedScriptValue.cpp	2012-12-07 16:54:31 UTC (rev 136957)
+++ trunk/Source/WebCore/bindings/js/SerializedScriptValue.cpp	2012-12-07 17:52:36 UTC (rev 136958)
@@ -1985,4 +1985,9 @@
     return (code == SuccessfullyCompleted);
 }
 
+uint32_t SerializedScriptValue::wireFormatVersion()
+{
+    return CurrentVersion;
 }
+
+}

Modified: trunk/Source/WebCore/bindings/js/SerializedScriptValue.h (136957 => 136958)


--- trunk/Source/WebCore/bindings/js/SerializedScriptValue.h	2012-12-07 16:54:31 UTC (rev 136957)
+++ trunk/Source/WebCore/bindings/js/SerializedScriptValue.h	2012-12-07 17:52:36 UTC (rev 136958)
@@ -83,6 +83,8 @@
     static PassRefPtr<SerializedScriptValue> undefinedValue();
     static PassRefPtr<SerializedScriptValue> booleanValue(bool value);
 
+    static uint32_t wireFormatVersion();
+
     String toString();
     
     JSC::JSValue deserialize(JSC::ExecState*, JSC::JSGlobalObject*, MessagePortArray*, SerializationErrorMode = Throwing);

Modified: trunk/Source/WebCore/bindings/v8/SerializedScriptValue.cpp (136957 => 136958)


--- trunk/Source/WebCore/bindings/v8/SerializedScriptValue.cpp	2012-12-07 16:54:31 UTC (rev 136957)
+++ trunk/Source/WebCore/bindings/v8/SerializedScriptValue.cpp	2012-12-07 17:52:36 UTC (rev 136958)
@@ -2449,4 +2449,9 @@
     }
 }
 
+uint32_t SerializedScriptValue::wireFormatVersion()
+{
+    return WebCore::wireFormatVersion;
+}
+
 } // namespace WebCore

Modified: trunk/Source/WebCore/bindings/v8/SerializedScriptValue.h (136957 => 136958)


--- trunk/Source/WebCore/bindings/v8/SerializedScriptValue.h	2012-12-07 16:54:31 UTC (rev 136957)
+++ trunk/Source/WebCore/bindings/v8/SerializedScriptValue.h	2012-12-07 17:52:36 UTC (rev 136958)
@@ -65,6 +65,8 @@
     static PassRefPtr<SerializedScriptValue> booleanValue(bool value, v8::Isolate* = 0);
     static PassRefPtr<SerializedScriptValue> numberValue(double value, v8::Isolate* = 0);
 
+    static uint32_t wireFormatVersion();
+
     PassRefPtr<SerializedScriptValue> release();
 
     String toWireString() const { return m_data; }
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
http://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to