Title: [96007] trunk/Source/WebCore
Revision
96007
Author
commit-qu...@webkit.org
Date
2011-09-26 15:22:23 -0700 (Mon, 26 Sep 2011)

Log Message

IndexedDB: Null key path gets stored as empty string key path
https://bugs.webkit.org/show_bug.cgi?id=68726

Patch by Joshua Bell <jsb...@chromium.org> on 2011-09-26
Reviewed by Tony Chang.

Store additional flag to indicate if object store key path
is null vs. empty. Added additional runtime tests for integrity
of object store metadata.

* storage/IDBLevelDBBackingStore.cpp:
(WebCore::checkObjectStoreAndMetaDataType):
(WebCore::IDBLevelDBBackingStore::getObjectStores):
(WebCore::IDBLevelDBBackingStore::createObjectStore):
* storage/IDBLevelDBCoding.cpp:

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (96006 => 96007)


--- trunk/Source/WebCore/ChangeLog	2011-09-26 22:21:04 UTC (rev 96006)
+++ trunk/Source/WebCore/ChangeLog	2011-09-26 22:22:23 UTC (rev 96007)
@@ -1,3 +1,20 @@
+2011-09-26  Joshua Bell  <jsb...@chromium.org>
+
+        IndexedDB: Null key path gets stored as empty string key path
+        https://bugs.webkit.org/show_bug.cgi?id=68726
+
+        Reviewed by Tony Chang.
+
+        Store additional flag to indicate if object store key path
+        is null vs. empty. Added additional runtime tests for integrity
+        of object store metadata.
+
+        * storage/IDBLevelDBBackingStore.cpp:
+        (WebCore::checkObjectStoreAndMetaDataType):
+        (WebCore::IDBLevelDBBackingStore::getObjectStores):
+        (WebCore::IDBLevelDBBackingStore::createObjectStore):
+        * storage/IDBLevelDBCoding.cpp:
+
 2011-09-26  John Bauman  <jbau...@chromium.org>
 
         Fix nonpremultiplied webgl toDataURL to jpeg

Modified: trunk/Source/WebCore/storage/IDBLevelDBBackingStore.cpp (96006 => 96007)


--- trunk/Source/WebCore/storage/IDBLevelDBBackingStore.cpp	2011-09-26 22:21:04 UTC (rev 96006)
+++ trunk/Source/WebCore/storage/IDBLevelDBBackingStore.cpp	2011-09-26 22:22:23 UTC (rev 96007)
@@ -212,59 +212,91 @@
     return true;
 }
 
+static bool checkObjectStoreAndMetaDataType(const LevelDBIterator* it, const Vector<char>& stopKey, int64_t objectStoreId, int64_t metaDataType)
+{
+    if (!it->isValid() || compareKeys(it->key(), stopKey) >= 0)
+        return false;
+
+    ObjectStoreMetaDataKey metaDataKey;
+    const char* p = ObjectStoreMetaDataKey::decode(it->key().begin(), it->key().end(), &metaDataKey);
+    ASSERT_UNUSED(p, p);
+    if (metaDataKey.objectStoreId() != objectStoreId)
+        return false;
+    if (metaDataKey.metaDataType() != metaDataType)
+        return false;
+    return true;
+}
+
 void IDBLevelDBBackingStore::getObjectStores(int64_t databaseId, Vector<int64_t>& foundIds, Vector<String>& foundNames, Vector<String>& foundKeyPaths, Vector<bool>& foundAutoIncrementFlags)
 {
     const Vector<char> startKey = ObjectStoreMetaDataKey::encode(databaseId, 1, 0);
     const Vector<char> stopKey = ObjectStoreMetaDataKey::encodeMaxKey(databaseId);
 
     OwnPtr<LevelDBIterator> it = m_db->createIterator();
-    for (it->seek(startKey); it->isValid() && compareKeys(it->key(), stopKey) < 0; it->next()) {
+    it->seek(startKey);
+    while (it->isValid() && compareKeys(it->key(), stopKey) < 0) {
         const char *p = it->key().begin();
         const char *limit = it->key().end();
 
         ObjectStoreMetaDataKey metaDataKey;
         p = ObjectStoreMetaDataKey::decode(p, limit, &metaDataKey);
         ASSERT(p);
+        if (metaDataKey.metaDataType()) {
+            LOG_ERROR("Internal Indexed DB error.");
+            return;
+        }
 
         int64_t objectStoreId = metaDataKey.objectStoreId();
-
         String objectStoreName = decodeString(it->value().begin(), it->value().end());
 
         it->next();
-        if (!it->isValid()) {
+        if (!checkObjectStoreAndMetaDataType(it.get(), stopKey, objectStoreId, 1)) {
             LOG_ERROR("Internal Indexed DB error.");
             return;
         }
         String keyPath = decodeString(it->value().begin(), it->value().end());
+        bool hasKeyPath = true;
 
         it->next();
-        if (!it->isValid()) {
+        if (!checkObjectStoreAndMetaDataType(it.get(), stopKey, objectStoreId, 2)) {
             LOG_ERROR("Internal Indexed DB error.");
             return;
         }
+        // FIXME: Add encode/decode functions for bools
         bool autoIncrement = *it->value().begin();
 
         it->next(); // Is evicatble.
-        if (!it->isValid()) {
+        if (!checkObjectStoreAndMetaDataType(it.get(), stopKey, objectStoreId, 3)) {
             LOG_ERROR("Internal Indexed DB error.");
             return;
         }
 
         it->next(); // Last version.
-        if (!it->isValid()) {
+        if (!checkObjectStoreAndMetaDataType(it.get(), stopKey, objectStoreId, 4)) {
             LOG_ERROR("Internal Indexed DB error.");
             return;
         }
 
         it->next(); // Maxium index id allocated.
-        if (!it->isValid()) {
+        if (!checkObjectStoreAndMetaDataType(it.get(), stopKey, objectStoreId, 5)) {
             LOG_ERROR("Internal Indexed DB error.");
             return;
         }
 
+        it->next(); // [optional] has key path (is not null)
+        if (checkObjectStoreAndMetaDataType(it.get(), stopKey, objectStoreId, 6)) {
+            // FIXME: Add encode/decode functions for bools
+            hasKeyPath = *it->value().begin();
+            if (!hasKeyPath && !keyPath.isEmpty()) {
+                LOG_ERROR("Internal Indexed DB error.");
+                return;
+            }
+            it->next();
+        }
+
         foundIds.append(objectStoreId);
         foundNames.append(objectStoreName);
-        foundKeyPaths.append(keyPath);
+        foundKeyPaths.append(hasKeyPath ? keyPath : String());
         foundAutoIncrementFlags.append(autoIncrement);
     }
 }
@@ -298,6 +330,7 @@
     const Vector<char> evictableKey = ObjectStoreMetaDataKey::encode(databaseId, objectStoreId, 3);
     const Vector<char> lastVersionKey = ObjectStoreMetaDataKey::encode(databaseId, objectStoreId, 4);
     const Vector<char> maxIndexIdKey = ObjectStoreMetaDataKey::encode(databaseId, objectStoreId, 5);
+    const Vector<char> hasKeyPathKey  = ObjectStoreMetaDataKey::encode(databaseId, objectStoreId, 6);
     const Vector<char> namesKey = ObjectStoreNamesKey::encode(databaseId, name);
 
     bool ok = putString(m_currentTransaction.get(), nameKey, name);
@@ -336,6 +369,12 @@
         return false;
     }
 
+    ok = putInt(m_currentTransaction.get(), hasKeyPathKey, !keyPath.isNull());
+    if (!ok) {
+        LOG_ERROR("Internal Indexed DB error.");
+        return false;
+    }
+
     ok = putInt(m_currentTransaction.get(), namesKey, objectStoreId);
     if (!ok) {
         LOG_ERROR("Internal Indexed DB error.");
@@ -365,7 +404,7 @@
     String objectStoreName;
     getString(m_currentTransaction.get(), ObjectStoreMetaDataKey::encode(databaseId, objectStoreId, 0), objectStoreName);
 
-    if (!deleteRange(m_currentTransaction.get(), ObjectStoreMetaDataKey::encode(databaseId, objectStoreId, 0), ObjectStoreMetaDataKey::encode(databaseId, objectStoreId, 6)))
+    if (!deleteRange(m_currentTransaction.get(), ObjectStoreMetaDataKey::encode(databaseId, objectStoreId, 0), ObjectStoreMetaDataKey::encodeMaxKey(databaseId, objectStoreId)))
         return; // FIXME: Report error.
 
     m_currentTransaction->remove(ObjectStoreNamesKey::encode(databaseId, objectStoreName));

Modified: trunk/Source/WebCore/storage/IDBLevelDBCoding.cpp (96006 => 96007)


--- trunk/Source/WebCore/storage/IDBLevelDBCoding.cpp	2011-09-26 22:21:04 UTC (rev 96006)
+++ trunk/Source/WebCore/storage/IDBLevelDBCoding.cpp	2011-09-26 22:22:23 UTC (rev 96007)
@@ -71,6 +71,7 @@
 //     <database id, 0, 0, 50, object store id, 3> => is evictable [ObjectStoreMetaDataKey]
 //     <database id, 0, 0, 50, object store id, 4> => last "version" number [ObjectStoreMetaDataKey]
 //     <database id, 0, 0, 50, object store id, 5> => maximum index id ever allocated [ObjectStoreMetaDataKey]
+//     <database id, 0, 0, 50, object store id, 6> => has key path (vs. null) [ObjectStoreMetaDataKey]
 //
 //
 // Index meta-data:
@@ -877,6 +878,11 @@
     return encode(databaseId, INT64_MAX, INT64_MAX);
 }
 
+Vector<char> ObjectStoreMetaDataKey::encodeMaxKey(int64_t databaseId, int64_t objectStoreId)
+{
+    return encode(databaseId, objectStoreId, INT64_MAX);
+}
+
 int64_t ObjectStoreMetaDataKey::objectStoreId() const
 {
     ASSERT(m_objectStoreId >= 0);

Modified: trunk/Source/WebCore/storage/IDBLevelDBCoding.h (96006 => 96007)


--- trunk/Source/WebCore/storage/IDBLevelDBCoding.h	2011-09-26 22:21:04 UTC (rev 96006)
+++ trunk/Source/WebCore/storage/IDBLevelDBCoding.h	2011-09-26 22:22:23 UTC (rev 96007)
@@ -144,6 +144,7 @@
     static const char* decode(const char* start, const char* limit, ObjectStoreMetaDataKey* result);
     static Vector<char> encode(int64_t databaseId, int64_t objectStoreId, int64_t metaDataType);
     static Vector<char> encodeMaxKey(int64_t databaseId);
+    static Vector<char> encodeMaxKey(int64_t databaseId, int64_t objectStoreId);
     int64_t objectStoreId() const;
     int64_t metaDataType() const;
     int compare(const ObjectStoreMetaDataKey& other);
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to