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; }