Modified: trunk/Source/WebCore/Modules/indexeddb/IDBLevelDBCoding.cpp (143346 => 143347)
--- trunk/Source/WebCore/Modules/indexeddb/IDBLevelDBCoding.cpp 2013-02-19 17:12:41 UTC (rev 143346)
+++ trunk/Source/WebCore/Modules/indexeddb/IDBLevelDBCoding.cpp 2013-02-19 17:42:55 UTC (rev 143347)
@@ -335,17 +335,15 @@
ASSERT(limit >= p);
int64_t len;
p = decodeVarInt(p, limit, len);
- if (!p)
+ if (!p || len < 0 || p + len * 2 > limit)
return 0;
- if (p + len * 2 > limit)
- return 0;
foundString = decodeString(p, p + len * 2);
p += len * 2;
return p;
}
-int compareEncodedStringsWithLength(const char*& p, const char* limitP, const char*& q, const char* limitQ)
+int compareEncodedStringsWithLength(const char*& p, const char* limitP, const char*& q, const char* limitQ, bool& ok)
{
ASSERT(&p != &q);
ASSERT(limitP >= p);
@@ -353,6 +351,10 @@
int64_t lenP, lenQ;
p = decodeVarInt(p, limitP, lenP);
q = decodeVarInt(q, limitQ, lenQ);
+ if (!p || !q || lenP < 0 || lenQ < 0) {
+ ok = false;
+ return 0;
+ }
ASSERT(p && q);
ASSERT(lenP >= 0);
ASSERT(lenQ >= 0);
@@ -364,9 +366,12 @@
p += lenP * 2;
q += lenQ * 2;
- if (p > limitP || q > limitQ)
+ if (p > limitP || q > limitQ) {
+ ok = false;
return 0;
+ }
+ ok = true;
const size_t lmin = static_cast<size_t>(lenP < lenQ ? lenP : lenQ);
if (int x = memcmp(startP, startQ, lmin * 2))
return x;
@@ -462,10 +467,8 @@
case IDBKeyArrayTypeByte: {
int64_t length;
p = decodeVarInt(p, limit, length);
- if (!p)
+ if (!p || length < 0)
return 0;
- if (length < 0)
- return 0;
IDBKey::KeyArray array;
while (length--) {
RefPtr<IDBKey> key;
@@ -522,10 +525,8 @@
case IDBKeyArrayTypeByte: {
int64_t length;
p = decodeVarInt(p, limit, length);
- if (!p)
+ if (!p || length < 0)
return 0;
- if (length < 0)
- return 0;
while (length--) {
p = extractEncodedIDBKey(p, limit);
if (!p)
@@ -536,10 +537,8 @@
case IDBKeyStringTypeByte: {
int64_t length;
p = decodeVarInt(p, limit, length);
- if (!p)
+ if (!p || length < 0 || p + length * 2 > limit)
return 0;
- if (p + length * 2 > limit)
- return 0;
p += length * 2;
break;
}
@@ -582,8 +581,9 @@
return IDBKey::InvalidType;
}
-int compareEncodedIDBKeys(const char*& ptrA, const char* limitA, const char*& ptrB, const char* limitB)
+int compareEncodedIDBKeys(const char*& ptrA, const char* limitA, const char*& ptrB, const char* limitB, bool& ok)
{
+ ok = true;
ASSERT(&ptrA != &ptrB);
ASSERT(ptrA < limitA);
ASSERT(ptrB < limitB);
@@ -601,16 +601,15 @@
case IDBKeyArrayTypeByte: {
int64_t lengthA, lengthB;
ptrA = decodeVarInt(ptrA, limitA, lengthA);
- if (!ptrA)
- return 0;
ptrB = decodeVarInt(ptrB, limitB, lengthB);
- if (!ptrB)
+ if (!ptrA || !ptrB || lengthA < 0 || lengthB < 0) {
+ ok = false;
return 0;
- if (lengthA < 0 || lengthB < 0)
- return 0;
+ }
for (int64_t i = 0; i < lengthA && i < lengthB; ++i) {
- if (int cmp = compareEncodedIDBKeys(ptrA, limitA, ptrB, limitB))
- return cmp;
+ int result = compareEncodedIDBKeys(ptrA, limitA, ptrB, limitB, ok);
+ if (!ok || result)
+ return result;
}
if (lengthA < lengthB)
return -1;
@@ -619,14 +618,18 @@
return 0;
}
case IDBKeyStringTypeByte:
- return compareEncodedStringsWithLength(ptrA, limitA, ptrB, limitB);
+ return compareEncodedStringsWithLength(ptrA, limitA, ptrB, limitB, ok);
case IDBKeyDateTypeByte:
case IDBKeyNumberTypeByte: {
double d, e;
ptrA = decodeDouble(ptrA, limitA, &d);
+ ptrB = decodeDouble(ptrB, limitB, &e);
ASSERT(ptrA);
- ptrB = decodeDouble(ptrB, limitB, &e);
ASSERT(ptrB);
+ if (!ptrA || !ptrB) {
+ ok = false;
+ return 0;
+ }
if (d < e)
return -1;
if (d > e)
@@ -639,7 +642,7 @@
return 0;
}
-int compareEncodedIDBKeys(const Vector<char>& keyA, const Vector<char>& keyB)
+int compareEncodedIDBKeys(const Vector<char>& keyA, const Vector<char>& keyB, bool& ok)
{
ASSERT(keyA.size() >= 1);
ASSERT(keyB.size() >= 1);
@@ -649,7 +652,7 @@
const char* ptrB = keyB.data();
const char* limitB = ptrB + keyB.size();
- return compareEncodedIDBKeys(ptrA, limitA, ptrB, limitB);
+ return compareEncodedIDBKeys(ptrA, limitA, ptrB, limitB, ok);
}
Vector<char> encodeIDBKeyPath(const IDBKeyPath& keyPath)
@@ -723,21 +726,30 @@
namespace {
template<typename KeyType>
-int compare(const LevelDBSlice& a, const LevelDBSlice& b, bool ignoreDuplicates = false)
+int compare(const LevelDBSlice& a, const LevelDBSlice& b, bool ignoreDuplicates, bool& ok)
{
KeyType keyA;
KeyType keyB;
const char* ptrA = KeyType::decode(a.begin(), a.end(), &keyA);
- ASSERT_UNUSED(ptrA, ptrA);
+ ASSERT(ptrA);
+ if (!ptrA) {
+ ok = false;
+ return 0;
+ }
const char* ptrB = KeyType::decode(b.begin(), b.end(), &keyB);
- ASSERT_UNUSED(ptrB, ptrB);
+ ASSERT(ptrB);
+ if (!ptrB) {
+ ok = false;
+ return 0;
+ }
+ ok = true;
return keyA.compare(keyB);
}
template<>
-int compare<ExistsEntryKey>(const LevelDBSlice& a, const LevelDBSlice& b, bool ignoreDuplicates)
+int compare<ExistsEntryKey>(const LevelDBSlice& a, const LevelDBSlice& b, bool ignoreDuplicates, bool& ok)
{
KeyPrefix prefixA;
KeyPrefix prefixB;
@@ -756,11 +768,11 @@
// Prefixes are not compared - it is assumed this was already done.
ASSERT(!prefixA.compare(prefixB));
- return compareEncodedIDBKeys(ptrA, a.end(), ptrB, b.end());
+ return compareEncodedIDBKeys(ptrA, a.end(), ptrB, b.end(), ok);
}
template<>
-int compare<ObjectStoreDataKey>(const LevelDBSlice& a, const LevelDBSlice& b, bool ignoreDuplicates)
+int compare<ObjectStoreDataKey>(const LevelDBSlice& a, const LevelDBSlice& b, bool ignoreDuplicates, bool& ok)
{
KeyPrefix prefixA;
KeyPrefix prefixB;
@@ -779,11 +791,11 @@
// Prefixes are not compared - it is assumed this was already done.
ASSERT(!prefixA.compare(prefixB));
- return compareEncodedIDBKeys(ptrA, a.end(), ptrB, b.end());
+ return compareEncodedIDBKeys(ptrA, a.end(), ptrB, b.end(), ok);
}
template<>
-int compare<IndexDataKey>(const LevelDBSlice& a, const LevelDBSlice& b, bool ignoreDuplicates)
+int compare<IndexDataKey>(const LevelDBSlice& a, const LevelDBSlice& b, bool ignoreDuplicates, bool& ok)
{
KeyPrefix prefixA;
KeyPrefix prefixB;
@@ -803,8 +815,9 @@
ASSERT(!prefixA.compare(prefixB));
// index key
- if (int x = compareEncodedIDBKeys(ptrA, a.end(), ptrB, b.end()))
- return x;
+ int result = compareEncodedIDBKeys(ptrA, a.end(), ptrB, b.end(), ok);
+ if (!ok || result)
+ return result;
if (ignoreDuplicates)
return 0;
@@ -816,7 +829,7 @@
if (ptrB != b.end())
ptrB = decodeVarInt(ptrB, b.end(), sequenceNumberB);
- // primar key [optional]
+ // primary key [optional]
if (!ptrA || !ptrB)
return 0;
if (ptrA == a.end() && ptrB == b.end())
@@ -826,15 +839,14 @@
if (ptrB == b.end())
return 1;
- if (int x = compareEncodedIDBKeys(ptrA, a.end(), ptrB, b.end()))
- return x;
+ result = compareEncodedIDBKeys(ptrA, a.end(), ptrB, b.end(), ok);
+ if (!ok || result)
+ return result;
return compareInts(sequenceNumberA, sequenceNumberB);
}
-}
-
-int compare(const LevelDBSlice& a, const LevelDBSlice& b, bool indexKeys)
+int compare(const LevelDBSlice& a, const LevelDBSlice& b, bool indexKeys, bool& ok)
{
const char* ptrA = a.begin();
const char* ptrB = b.begin();
@@ -848,7 +860,12 @@
ptrB = KeyPrefix::decode(ptrB, endB, &prefixB);
ASSERT(ptrA);
ASSERT(ptrB);
+ if (!ptrA || !ptrB) {
+ ok = false;
+ return 0;
+ }
+ ok = true;
if (int x = prefixA.compare(prefixB))
return x;
@@ -864,10 +881,11 @@
if (typeByteA < MaxSimpleGlobalMetaDataTypeByte)
return 0;
+ const bool ignoreDuplicates = false;
if (typeByteA == DatabaseFreeListTypeByte)
- return compare<DatabaseFreeListKey>(a, b);
+ return compare<DatabaseFreeListKey>(a, b, ignoreDuplicates, ok);
if (typeByteA == DatabaseNameTypeByte)
- return compare<DatabaseNameKey>(a, b);
+ return compare<DatabaseNameKey>(a, b, ignoreDuplicates, ok);
}
if (prefixA.type() == KeyPrefix::DatabaseMetaData) {
@@ -882,18 +900,19 @@
if (typeByteA < DatabaseMetaDataKey::MaxSimpleMetaDataType)
return 0;
+ const bool ignoreDuplicates = false;
if (typeByteA == ObjectStoreMetaDataTypeByte)
- return compare<ObjectStoreMetaDataKey>(a, b);
+ return compare<ObjectStoreMetaDataKey>(a, b, ignoreDuplicates, ok);
if (typeByteA == IndexMetaDataTypeByte)
- return compare<IndexMetaDataKey>(a, b);
+ return compare<IndexMetaDataKey>(a, b, ignoreDuplicates, ok);
if (typeByteA == ObjectStoreFreeListTypeByte)
- return compare<ObjectStoreFreeListKey>(a, b);
+ return compare<ObjectStoreFreeListKey>(a, b, ignoreDuplicates, ok);
if (typeByteA == IndexFreeListTypeByte)
- return compare<IndexFreeListKey>(a, b);
+ return compare<IndexFreeListKey>(a, b, ignoreDuplicates, ok);
if (typeByteA == ObjectStoreNamesTypeByte)
- return compare<ObjectStoreNamesKey>(a, b);
+ return compare<ObjectStoreNamesKey>(a, b, ignoreDuplicates, ok);
if (typeByteA == IndexNamesKeyTypeByte)
- return compare<IndexNamesKey>(a, b);
+ return compare<IndexNamesKey>(a, b, ignoreDuplicates, ok);
}
if (prefixA.type() == KeyPrefix::ObjectStoreData) {
@@ -904,7 +923,8 @@
if (ptrB == endB)
return 1; // FIXME: This case of non-existing user keys should not have to be handled this way.
- return compare<ObjectStoreDataKey>(a, b);
+ const bool ignoreDuplicates = false;
+ return compare<ObjectStoreDataKey>(a, b, ignoreDuplicates, ok);
}
if (prefixA.type() == KeyPrefix::ExistsEntry) {
if (ptrA == endA && ptrB == endB)
@@ -914,7 +934,8 @@
if (ptrB == endB)
return 1; // FIXME: This case of non-existing user keys should not have to be handled this way.
- return compare<ExistsEntryKey>(a, b);
+ const bool ignoreDuplicates = false;
+ return compare<ExistsEntryKey>(a, b, ignoreDuplicates, ok);
}
if (prefixA.type() == KeyPrefix::IndexData) {
if (ptrA == endA && ptrB == endB)
@@ -925,14 +946,26 @@
return 1; // FIXME: This case of non-existing user keys should not have to be handled this way.
bool ignoreDuplicates = indexKeys;
- return compare<IndexDataKey>(a, b, ignoreDuplicates);
+ return compare<IndexDataKey>(a, b, ignoreDuplicates, ok);
}
ASSERT_NOT_REACHED();
+ ok = false;
return 0;
}
+}
+int compare(const LevelDBSlice& a, const LevelDBSlice& b, bool indexKeys)
+{
+ bool ok;
+ int result = compare(a, b, indexKeys, ok);
+ ASSERT(ok);
+ if (!ok)
+ return 0;
+ return result;
+}
+
KeyPrefix::KeyPrefix()
: m_databaseId(InvalidType)
, m_objectStoreId(InvalidType)
@@ -1536,9 +1569,9 @@
return encode(databaseId, objectStoreId, encodeIDBKey(userKey));
}
-int ObjectStoreDataKey::compare(const ObjectStoreDataKey& other)
+int ObjectStoreDataKey::compare(const ObjectStoreDataKey& other, bool& ok)
{
- return compareEncodedIDBKeys(m_encodedUserKey, other.m_encodedUserKey);
+ return compareEncodedIDBKeys(m_encodedUserKey, other.m_encodedUserKey, ok);
}
PassRefPtr<IDBKey> ObjectStoreDataKey::userKey() const
@@ -1577,9 +1610,9 @@
return encode(databaseId, objectStoreId, encodeIDBKey(userKey));
}
-int ExistsEntryKey::compare(const ExistsEntryKey& other)
+int ExistsEntryKey::compare(const ExistsEntryKey& other, bool& ok)
{
- return compareEncodedIDBKeys(m_encodedUserKey, other.m_encodedUserKey);
+ return compareEncodedIDBKeys(m_encodedUserKey, other.m_encodedUserKey, ok);
}
PassRefPtr<IDBKey> ExistsEntryKey::userKey() const
@@ -1660,17 +1693,19 @@
return encode(databaseId, objectStoreId, indexId, maxIDBKey(), maxIDBKey(), INT64_MAX);
}
-int IndexDataKey::compare(const IndexDataKey& other, bool ignoreDuplicates)
+int IndexDataKey::compare(const IndexDataKey& other, bool ignoreDuplicates, bool& ok)
{
ASSERT(m_databaseId >= 0);
ASSERT(m_objectStoreId >= 0);
ASSERT(m_indexId >= 0);
- if (int x = compareEncodedIDBKeys(m_encodedUserKey, other.m_encodedUserKey))
- return x;
+ int result = compareEncodedIDBKeys(m_encodedUserKey, other.m_encodedUserKey, ok);
+ if (!ok || result)
+ return result;
if (ignoreDuplicates)
return 0;
- if (int x = compareEncodedIDBKeys(m_encodedPrimaryKey, other.m_encodedPrimaryKey))
- return x;
+ result = compareEncodedIDBKeys(m_encodedPrimaryKey, other.m_encodedPrimaryKey, ok);
+ if (!ok || result)
+ return result;
return compareInts(m_sequenceNumber, other.m_sequenceNumber);
}
Modified: trunk/Source/WebCore/Modules/indexeddb/IDBLevelDBCoding.h (143346 => 143347)
--- trunk/Source/WebCore/Modules/indexeddb/IDBLevelDBCoding.h 2013-02-19 17:12:41 UTC (rev 143346)
+++ trunk/Source/WebCore/Modules/indexeddb/IDBLevelDBCoding.h 2013-02-19 17:42:55 UTC (rev 143347)
@@ -61,14 +61,14 @@
String decodeString(const char* p, const char* end);
Vector<char> encodeStringWithLength(const String&);
const char* decodeStringWithLength(const char* p, const char* limit, String& foundString);
-int compareEncodedStringsWithLength(const char*& p, const char* limitP, const char*& q, const char* limitQ);
+int compareEncodedStringsWithLength(const char*& p, const char* limitP, const char*& q, const char* limitQ, bool& ok);
Vector<char> encodeDouble(double);
const char* decodeDouble(const char* p, const char* limit, double*);
void encodeIDBKey(const IDBKey&, Vector<char, DefaultInlineBufferSize>& into);
Vector<char> encodeIDBKey(const IDBKey&);
const char* decodeIDBKey(const char* p, const char* limit, RefPtr<IDBKey>& foundKey);
const char* extractEncodedIDBKey(const char* start, const char* limit, Vector<char>* result);
-int compareEncodedIDBKeys(const Vector<char>&, const Vector<char>&);
+int compareEncodedIDBKeys(const Vector<char>&, const Vector<char>&, bool& ok);
Vector<char> encodeIDBKeyPath(const IDBKeyPath&);
IDBKeyPath decodeIDBKeyPath(const char*, const char*);
@@ -271,7 +271,7 @@
static const char* decode(const char* start, const char* end, ObjectStoreDataKey* result);
static Vector<char> encode(int64_t databaseId, int64_t objectStoreId, const Vector<char> encodedUserKey);
static Vector<char> encode(int64_t databaseId, int64_t objectStoreId, const IDBKey& userKey);
- int compare(const ObjectStoreDataKey& other);
+ int compare(const ObjectStoreDataKey& other, bool& ok);
PassRefPtr<IDBKey> userKey() const;
static const int64_t SpecialIndexNumber;
@@ -284,7 +284,7 @@
static const char* decode(const char* start, const char* end, ExistsEntryKey* result);
static Vector<char> encode(int64_t databaseId, int64_t objectStoreId, const Vector<char>& encodedKey);
static Vector<char> encode(int64_t databaseId, int64_t objectStoreId, const IDBKey& userKey);
- int compare(const ExistsEntryKey& other);
+ int compare(const ExistsEntryKey& other, bool& ok);
PassRefPtr<IDBKey> userKey() const;
static const int64_t SpecialIndexNumber;
@@ -301,7 +301,7 @@
static Vector<char> encode(int64_t databaseId, int64_t objectStoreId, int64_t indexId, const IDBKey& userKey);
static Vector<char> encodeMinKey(int64_t databaseId, int64_t objectStoreId, int64_t indexId);
static Vector<char> encodeMaxKey(int64_t databaseId, int64_t objectStoreId, int64_t indexId);
- int compare(const IndexDataKey& other, bool ignoreDuplicates);
+ int compare(const IndexDataKey& other, bool ignoreDuplicates, bool& ok);
int64_t databaseId() const;
int64_t objectStoreId() const;
int64_t indexId() const;
Modified: trunk/Source/WebKit/chromium/tests/IDBLevelDBCodingTest.cpp (143346 => 143347)
--- trunk/Source/WebKit/chromium/tests/IDBLevelDBCodingTest.cpp 2013-02-19 17:12:41 UTC (rev 143346)
+++ trunk/Source/WebKit/chromium/tests/IDBLevelDBCodingTest.cpp 2013-02-19 17:42:55 UTC (rev 143347)
@@ -116,6 +116,14 @@
}
}
+static int compareKeys(const Vector<char>& a, const Vector<char>& b)
+{
+ bool ok;
+ int result = compareEncodedIDBKeys(a, b, ok);
+ EXPECT_TRUE(ok);
+ return result;
+}
+
TEST(IDBLevelDBCodingTest, MaxIDBKey)
{
Vector<char> maxKey = maxIDBKey();
@@ -126,11 +134,11 @@
Vector<char> numberKey = encodeIDBKey(*IDBKey::createNumber(3.14));
Vector<char> dateKey = encodeIDBKey(*IDBKey::createDate(1000000));
- EXPECT_GT(compareEncodedIDBKeys(maxKey, minKey), 0);
- EXPECT_GT(compareEncodedIDBKeys(maxKey, arrayKey), 0);
- EXPECT_GT(compareEncodedIDBKeys(maxKey, stringKey), 0);
- EXPECT_GT(compareEncodedIDBKeys(maxKey, numberKey), 0);
- EXPECT_GT(compareEncodedIDBKeys(maxKey, dateKey), 0);
+ EXPECT_GT(compareKeys(maxKey, minKey), 0);
+ EXPECT_GT(compareKeys(maxKey, arrayKey), 0);
+ EXPECT_GT(compareKeys(maxKey, stringKey), 0);
+ EXPECT_GT(compareKeys(maxKey, numberKey), 0);
+ EXPECT_GT(compareKeys(maxKey, dateKey), 0);
}
TEST(IDBLevelDBCodingTest, MinIDBKey)
@@ -143,11 +151,11 @@
Vector<char> numberKey = encodeIDBKey(*IDBKey::createNumber(3.14));
Vector<char> dateKey = encodeIDBKey(*IDBKey::createDate(1000000));
- EXPECT_LT(compareEncodedIDBKeys(minKey, maxKey), 0);
- EXPECT_LT(compareEncodedIDBKeys(minKey, arrayKey), 0);
- EXPECT_LT(compareEncodedIDBKeys(minKey, stringKey), 0);
- EXPECT_LT(compareEncodedIDBKeys(minKey, numberKey), 0);
- EXPECT_LT(compareEncodedIDBKeys(minKey, dateKey), 0);
+ EXPECT_LT(compareKeys(minKey, maxKey), 0);
+ EXPECT_LT(compareKeys(minKey, arrayKey), 0);
+ EXPECT_LT(compareKeys(minKey, stringKey), 0);
+ EXPECT_LT(compareKeys(minKey, numberKey), 0);
+ EXPECT_LT(compareKeys(minKey, dateKey), 0);
}
TEST(IDBLevelDBCodingTest, EncodeInt)
@@ -322,7 +330,9 @@
static int compareStrings(const char* p, const char* limitP, const char* q, const char* limitQ)
{
- int result = compareEncodedStringsWithLength(p, limitP, q, limitQ);
+ bool ok;
+ int result = compareEncodedStringsWithLength(p, limitP, q, limitQ, ok);
+ EXPECT_TRUE(ok);
EXPECT_EQ(p, limitP);
EXPECT_EQ(q, limitQ);
return result;
@@ -631,10 +641,10 @@
EXPECT_EQ(encodedB.data() + encodedB.size(), q);
EXPECT_EQ(encodedB, extractedB);
- EXPECT_LT(compareEncodedIDBKeys(extractedA, extractedB), 0);
- EXPECT_GT(compareEncodedIDBKeys(extractedB, extractedA), 0);
- EXPECT_EQ(compareEncodedIDBKeys(extractedA, extractedA), 0);
- EXPECT_EQ(compareEncodedIDBKeys(extractedB, extractedB), 0);
+ EXPECT_LT(compareKeys(extractedA, extractedB), 0);
+ EXPECT_GT(compareKeys(extractedB, extractedA), 0);
+ EXPECT_EQ(compareKeys(extractedA, extractedA), 0);
+ EXPECT_EQ(compareKeys(extractedB, extractedB), 0);
EXPECT_EQ(0, extractEncodedIDBKey(encodedA.data(), encodedA.data() + encodedA.size() - 1, &extractedA));
}