1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "content/browser/indexed_db/indexed_db_leveldb_coding.h" 6 7 #include <limits> 8 #include <vector> 9 10 #include "base/basictypes.h" 11 #include "base/strings/string16.h" 12 #include "base/strings/string_piece.h" 13 #include "base/strings/utf_string_conversions.h" 14 #include "content/common/indexed_db/indexed_db_key.h" 15 #include "content/common/indexed_db/indexed_db_key_path.h" 16 #include "testing/gtest/include/gtest/gtest.h" 17 18 using base::StringPiece; 19 using blink::WebIDBKeyTypeDate; 20 using blink::WebIDBKeyTypeNumber; 21 22 namespace content { 23 24 namespace { 25 26 static IndexedDBKey CreateArrayIDBKey() { 27 return IndexedDBKey(IndexedDBKey::KeyArray()); 28 } 29 30 static IndexedDBKey CreateArrayIDBKey(const IndexedDBKey& key1) { 31 IndexedDBKey::KeyArray array; 32 array.push_back(key1); 33 return IndexedDBKey(array); 34 } 35 36 static IndexedDBKey CreateArrayIDBKey(const IndexedDBKey& key1, 37 const IndexedDBKey& key2) { 38 IndexedDBKey::KeyArray array; 39 array.push_back(key1); 40 array.push_back(key2); 41 return IndexedDBKey(array); 42 } 43 44 static std::string WrappedEncodeByte(char value) { 45 std::string buffer; 46 EncodeByte(value, &buffer); 47 return buffer; 48 } 49 50 TEST(IndexedDBLevelDBCodingTest, EncodeByte) { 51 std::string expected; 52 expected.push_back(0); 53 unsigned char c; 54 55 c = 0; 56 expected[0] = c; 57 EXPECT_EQ(expected, WrappedEncodeByte(c)); 58 59 c = 1; 60 expected[0] = c; 61 EXPECT_EQ(expected, WrappedEncodeByte(c)); 62 63 c = 255; 64 expected[0] = c; 65 EXPECT_EQ(expected, WrappedEncodeByte(c)); 66 } 67 68 TEST(IndexedDBLevelDBCodingTest, DecodeByte) { 69 std::vector<unsigned char> test_cases; 70 test_cases.push_back(0); 71 test_cases.push_back(1); 72 test_cases.push_back(255); 73 74 for (size_t i = 0; i < test_cases.size(); ++i) { 75 unsigned char n = test_cases[i]; 76 std::string v; 77 EncodeByte(n, &v); 78 79 unsigned char res; 80 ASSERT_GT(v.size(), static_cast<size_t>(0)); 81 StringPiece slice(v); 82 EXPECT_TRUE(DecodeByte(&slice, &res)); 83 EXPECT_EQ(n, res); 84 EXPECT_TRUE(slice.empty()); 85 } 86 87 { 88 StringPiece slice; 89 unsigned char value; 90 EXPECT_FALSE(DecodeByte(&slice, &value)); 91 } 92 } 93 94 static std::string WrappedEncodeBool(bool value) { 95 std::string buffer; 96 EncodeBool(value, &buffer); 97 return buffer; 98 } 99 100 TEST(IndexedDBLevelDBCodingTest, EncodeBool) { 101 { 102 std::string expected; 103 expected.push_back(1); 104 EXPECT_EQ(expected, WrappedEncodeBool(true)); 105 } 106 { 107 std::string expected; 108 expected.push_back(0); 109 EXPECT_EQ(expected, WrappedEncodeBool(false)); 110 } 111 } 112 113 static int CompareKeys(const std::string& a, const std::string& b) { 114 DCHECK(!a.empty()); 115 DCHECK(!b.empty()); 116 117 StringPiece slice_a(a); 118 StringPiece slice_b(b); 119 bool ok; 120 int result = CompareEncodedIDBKeys(&slice_a, &slice_b, &ok); 121 EXPECT_TRUE(ok); 122 return result; 123 } 124 125 TEST(IndexedDBLevelDBCodingTest, MaxIDBKey) { 126 std::string max_key = MaxIDBKey(); 127 128 std::string min_key = MinIDBKey(); 129 std::string array_key; 130 EncodeIDBKey(IndexedDBKey(IndexedDBKey::KeyArray()), &array_key); 131 std::string binary_key; 132 EncodeIDBKey(IndexedDBKey(std::string("\x00\x01\x02")), &binary_key); 133 std::string string_key; 134 EncodeIDBKey(IndexedDBKey(ASCIIToUTF16("Hello world")), &string_key); 135 std::string number_key; 136 EncodeIDBKey(IndexedDBKey(3.14, WebIDBKeyTypeNumber), &number_key); 137 std::string date_key; 138 EncodeIDBKey(IndexedDBKey(1000000, WebIDBKeyTypeDate), &date_key); 139 140 EXPECT_GT(CompareKeys(max_key, min_key), 0); 141 EXPECT_GT(CompareKeys(max_key, array_key), 0); 142 EXPECT_GT(CompareKeys(max_key, binary_key), 0); 143 EXPECT_GT(CompareKeys(max_key, string_key), 0); 144 EXPECT_GT(CompareKeys(max_key, number_key), 0); 145 EXPECT_GT(CompareKeys(max_key, date_key), 0); 146 } 147 148 TEST(IndexedDBLevelDBCodingTest, MinIDBKey) { 149 std::string min_key = MinIDBKey(); 150 151 std::string max_key = MaxIDBKey(); 152 std::string array_key; 153 EncodeIDBKey(IndexedDBKey(IndexedDBKey::KeyArray()), &array_key); 154 std::string binary_key; 155 EncodeIDBKey(IndexedDBKey(std::string("\x00\x01\x02")), &binary_key); 156 std::string string_key; 157 EncodeIDBKey(IndexedDBKey(ASCIIToUTF16("Hello world")), &string_key); 158 std::string number_key; 159 EncodeIDBKey(IndexedDBKey(3.14, WebIDBKeyTypeNumber), &number_key); 160 std::string date_key; 161 EncodeIDBKey(IndexedDBKey(1000000, WebIDBKeyTypeDate), &date_key); 162 163 EXPECT_LT(CompareKeys(min_key, max_key), 0); 164 EXPECT_LT(CompareKeys(min_key, array_key), 0); 165 EXPECT_LT(CompareKeys(min_key, binary_key), 0); 166 EXPECT_LT(CompareKeys(min_key, string_key), 0); 167 EXPECT_LT(CompareKeys(min_key, number_key), 0); 168 EXPECT_LT(CompareKeys(min_key, date_key), 0); 169 } 170 171 static std::string WrappedEncodeInt(int64 value) { 172 std::string buffer; 173 EncodeInt(value, &buffer); 174 return buffer; 175 } 176 177 TEST(IndexedDBLevelDBCodingTest, EncodeInt) { 178 EXPECT_EQ(static_cast<size_t>(1), WrappedEncodeInt(0).size()); 179 EXPECT_EQ(static_cast<size_t>(1), WrappedEncodeInt(1).size()); 180 EXPECT_EQ(static_cast<size_t>(1), WrappedEncodeInt(255).size()); 181 EXPECT_EQ(static_cast<size_t>(2), WrappedEncodeInt(256).size()); 182 EXPECT_EQ(static_cast<size_t>(4), WrappedEncodeInt(0xffffffff).size()); 183 #ifdef NDEBUG 184 EXPECT_EQ(static_cast<size_t>(8), WrappedEncodeInt(-1).size()); 185 #endif 186 } 187 188 TEST(IndexedDBLevelDBCodingTest, DecodeBool) { 189 { 190 std::string encoded; 191 encoded.push_back(1); 192 StringPiece slice(encoded); 193 bool value; 194 EXPECT_TRUE(DecodeBool(&slice, &value)); 195 EXPECT_TRUE(value); 196 EXPECT_TRUE(slice.empty()); 197 } 198 { 199 std::string encoded; 200 encoded.push_back(0); 201 StringPiece slice(encoded); 202 bool value; 203 EXPECT_TRUE(DecodeBool(&slice, &value)); 204 EXPECT_FALSE(value); 205 EXPECT_TRUE(slice.empty()); 206 } 207 { 208 StringPiece slice; 209 bool value; 210 EXPECT_FALSE(DecodeBool(&slice, &value)); 211 } 212 } 213 214 TEST(IndexedDBLevelDBCodingTest, DecodeInt) { 215 std::vector<int64> test_cases; 216 test_cases.push_back(0); 217 test_cases.push_back(1); 218 test_cases.push_back(255); 219 test_cases.push_back(256); 220 test_cases.push_back(65535); 221 test_cases.push_back(655536); 222 test_cases.push_back(7711192431755665792ll); 223 test_cases.push_back(0x7fffffffffffffffll); 224 #ifdef NDEBUG 225 test_cases.push_back(-3); 226 #endif 227 228 for (size_t i = 0; i < test_cases.size(); ++i) { 229 int64 n = test_cases[i]; 230 std::string v = WrappedEncodeInt(n); 231 ASSERT_GT(v.size(), static_cast<size_t>(0)); 232 StringPiece slice(v); 233 int64 value; 234 EXPECT_TRUE(DecodeInt(&slice, &value)); 235 EXPECT_EQ(n, value); 236 EXPECT_TRUE(slice.empty()); 237 238 // Verify decoding at an offset, to detect unaligned memory access. 239 v.insert(v.begin(), static_cast<size_t>(1), static_cast<char>(0)); 240 slice = StringPiece(&*v.begin() + 1, v.size() - 1); 241 EXPECT_TRUE(DecodeInt(&slice, &value)); 242 EXPECT_EQ(n, value); 243 EXPECT_TRUE(slice.empty()); 244 } 245 { 246 StringPiece slice; 247 int64 value; 248 EXPECT_FALSE(DecodeInt(&slice, &value)); 249 } 250 } 251 252 static std::string WrappedEncodeVarInt(int64 value) { 253 std::string buffer; 254 EncodeVarInt(value, &buffer); 255 return buffer; 256 } 257 258 TEST(IndexedDBLevelDBCodingTest, EncodeVarInt) { 259 EXPECT_EQ(static_cast<size_t>(1), WrappedEncodeVarInt(0).size()); 260 EXPECT_EQ(static_cast<size_t>(1), WrappedEncodeVarInt(1).size()); 261 EXPECT_EQ(static_cast<size_t>(2), WrappedEncodeVarInt(255).size()); 262 EXPECT_EQ(static_cast<size_t>(2), WrappedEncodeVarInt(256).size()); 263 EXPECT_EQ(static_cast<size_t>(5), WrappedEncodeVarInt(0xffffffff).size()); 264 EXPECT_EQ(static_cast<size_t>(8), 265 WrappedEncodeVarInt(0xfffffffffffffLL).size()); 266 EXPECT_EQ(static_cast<size_t>(9), 267 WrappedEncodeVarInt(0x7fffffffffffffffLL).size()); 268 #ifdef NDEBUG 269 EXPECT_EQ(static_cast<size_t>(10), WrappedEncodeVarInt(-100).size()); 270 #endif 271 } 272 273 TEST(IndexedDBLevelDBCodingTest, DecodeVarInt) { 274 std::vector<int64> test_cases; 275 test_cases.push_back(0); 276 test_cases.push_back(1); 277 test_cases.push_back(255); 278 test_cases.push_back(256); 279 test_cases.push_back(65535); 280 test_cases.push_back(655536); 281 test_cases.push_back(7711192431755665792ll); 282 test_cases.push_back(0x7fffffffffffffffll); 283 #ifdef NDEBUG 284 test_cases.push_back(-3); 285 #endif 286 287 for (size_t i = 0; i < test_cases.size(); ++i) { 288 int64 n = test_cases[i]; 289 std::string v = WrappedEncodeVarInt(n); 290 ASSERT_GT(v.size(), static_cast<size_t>(0)); 291 StringPiece slice(v); 292 int64 res; 293 EXPECT_TRUE(DecodeVarInt(&slice, &res)); 294 EXPECT_EQ(n, res); 295 EXPECT_TRUE(slice.empty()); 296 297 slice = StringPiece(&*v.begin(), v.size() - 1); 298 EXPECT_FALSE(DecodeVarInt(&slice, &res)); 299 300 slice = StringPiece(&*v.begin(), static_cast<size_t>(0)); 301 EXPECT_FALSE(DecodeVarInt(&slice, &res)); 302 303 // Verify decoding at an offset, to detect unaligned memory access. 304 v.insert(v.begin(), static_cast<size_t>(1), static_cast<char>(0)); 305 slice = StringPiece(&*v.begin() + 1, v.size() - 1); 306 EXPECT_TRUE(DecodeVarInt(&slice, &res)); 307 EXPECT_EQ(n, res); 308 EXPECT_TRUE(slice.empty()); 309 } 310 } 311 312 static std::string WrappedEncodeString(base::string16 value) { 313 std::string buffer; 314 EncodeString(value, &buffer); 315 return buffer; 316 } 317 318 TEST(IndexedDBLevelDBCodingTest, EncodeString) { 319 const char16 test_string_a[] = {'f', 'o', 'o', '\0'}; 320 const char16 test_string_b[] = {0xdead, 0xbeef, '\0'}; 321 322 EXPECT_EQ(static_cast<size_t>(0), 323 WrappedEncodeString(ASCIIToUTF16("")).size()); 324 EXPECT_EQ(static_cast<size_t>(2), 325 WrappedEncodeString(ASCIIToUTF16("a")).size()); 326 EXPECT_EQ(static_cast<size_t>(6), 327 WrappedEncodeString(ASCIIToUTF16("foo")).size()); 328 EXPECT_EQ(static_cast<size_t>(6), 329 WrappedEncodeString(base::string16(test_string_a)).size()); 330 EXPECT_EQ(static_cast<size_t>(4), 331 WrappedEncodeString(base::string16(test_string_b)).size()); 332 } 333 334 TEST(IndexedDBLevelDBCodingTest, DecodeString) { 335 const char16 test_string_a[] = {'f', 'o', 'o', '\0'}; 336 const char16 test_string_b[] = {0xdead, 0xbeef, '\0'}; 337 338 std::vector<base::string16> test_cases; 339 test_cases.push_back(base::string16()); 340 test_cases.push_back(ASCIIToUTF16("a")); 341 test_cases.push_back(ASCIIToUTF16("foo")); 342 test_cases.push_back(test_string_a); 343 test_cases.push_back(test_string_b); 344 345 for (size_t i = 0; i < test_cases.size(); ++i) { 346 const base::string16& test_case = test_cases[i]; 347 std::string v = WrappedEncodeString(test_case); 348 349 StringPiece slice; 350 if (v.size()) { 351 slice = StringPiece(&*v.begin(), v.size()); 352 } 353 354 base::string16 result; 355 EXPECT_TRUE(DecodeString(&slice, &result)); 356 EXPECT_EQ(test_case, result); 357 EXPECT_TRUE(slice.empty()); 358 359 // Verify decoding at an offset, to detect unaligned memory access. 360 v.insert(v.begin(), static_cast<size_t>(1), static_cast<char>(0)); 361 slice = StringPiece(&*v.begin() + 1, v.size() - 1); 362 EXPECT_TRUE(DecodeString(&slice, &result)); 363 EXPECT_EQ(test_case, result); 364 EXPECT_TRUE(slice.empty()); 365 } 366 } 367 368 static std::string WrappedEncodeStringWithLength(base::string16 value) { 369 std::string buffer; 370 EncodeStringWithLength(value, &buffer); 371 return buffer; 372 } 373 374 TEST(IndexedDBLevelDBCodingTest, EncodeStringWithLength) { 375 const char16 test_string_a[] = {'f', 'o', 'o', '\0'}; 376 const char16 test_string_b[] = {0xdead, 0xbeef, '\0'}; 377 378 EXPECT_EQ(static_cast<size_t>(1), 379 WrappedEncodeStringWithLength(base::string16()).size()); 380 EXPECT_EQ(static_cast<size_t>(3), 381 WrappedEncodeStringWithLength(ASCIIToUTF16("a")).size()); 382 EXPECT_EQ(static_cast<size_t>(7), 383 WrappedEncodeStringWithLength( 384 base::string16(test_string_a)).size()); 385 EXPECT_EQ(static_cast<size_t>(5), 386 WrappedEncodeStringWithLength( 387 base::string16(test_string_b)).size()); 388 } 389 390 TEST(IndexedDBLevelDBCodingTest, DecodeStringWithLength) { 391 const char16 test_string_a[] = {'f', 'o', 'o', '\0'}; 392 const char16 test_string_b[] = {0xdead, 0xbeef, '\0'}; 393 394 const int kLongStringLen = 1234; 395 char16 long_string[kLongStringLen + 1]; 396 for (int i = 0; i < kLongStringLen; ++i) 397 long_string[i] = i; 398 long_string[kLongStringLen] = 0; 399 400 std::vector<base::string16> test_cases; 401 test_cases.push_back(ASCIIToUTF16("")); 402 test_cases.push_back(ASCIIToUTF16("a")); 403 test_cases.push_back(ASCIIToUTF16("foo")); 404 test_cases.push_back(base::string16(test_string_a)); 405 test_cases.push_back(base::string16(test_string_b)); 406 test_cases.push_back(base::string16(long_string)); 407 408 for (size_t i = 0; i < test_cases.size(); ++i) { 409 base::string16 s = test_cases[i]; 410 std::string v = WrappedEncodeStringWithLength(s); 411 ASSERT_GT(v.size(), static_cast<size_t>(0)); 412 StringPiece slice(v); 413 base::string16 res; 414 EXPECT_TRUE(DecodeStringWithLength(&slice, &res)); 415 EXPECT_EQ(s, res); 416 EXPECT_TRUE(slice.empty()); 417 418 slice = StringPiece(&*v.begin(), v.size() - 1); 419 EXPECT_FALSE(DecodeStringWithLength(&slice, &res)); 420 421 slice = StringPiece(&*v.begin(), static_cast<size_t>(0)); 422 EXPECT_FALSE(DecodeStringWithLength(&slice, &res)); 423 424 // Verify decoding at an offset, to detect unaligned memory access. 425 v.insert(v.begin(), static_cast<size_t>(1), static_cast<char>(0)); 426 slice = StringPiece(&*v.begin() + 1, v.size() - 1); 427 EXPECT_TRUE(DecodeStringWithLength(&slice, &res)); 428 EXPECT_EQ(s, res); 429 EXPECT_TRUE(slice.empty()); 430 } 431 } 432 433 static int CompareStrings(const std::string& p, const std::string& q) { 434 bool ok; 435 DCHECK(!p.empty()); 436 DCHECK(!q.empty()); 437 StringPiece slice_p(p); 438 StringPiece slice_q(q); 439 int result = CompareEncodedStringsWithLength(&slice_p, &slice_q, &ok); 440 EXPECT_TRUE(ok); 441 EXPECT_TRUE(slice_p.empty()); 442 EXPECT_TRUE(slice_q.empty()); 443 return result; 444 } 445 446 TEST(IndexedDBLevelDBCodingTest, CompareEncodedStringsWithLength) { 447 const char16 test_string_a[] = {0x1000, 0x1000, '\0'}; 448 const char16 test_string_b[] = {0x1000, 0x1000, 0x1000, '\0'}; 449 const char16 test_string_c[] = {0x1000, 0x1000, 0x1001, '\0'}; 450 const char16 test_string_d[] = {0x1001, 0x1000, 0x1000, '\0'}; 451 const char16 test_string_e[] = {0xd834, 0xdd1e, '\0'}; 452 const char16 test_string_f[] = {0xfffd, '\0'}; 453 454 std::vector<base::string16> test_cases; 455 test_cases.push_back(ASCIIToUTF16("")); 456 test_cases.push_back(ASCIIToUTF16("a")); 457 test_cases.push_back(ASCIIToUTF16("b")); 458 test_cases.push_back(ASCIIToUTF16("baaa")); 459 test_cases.push_back(ASCIIToUTF16("baab")); 460 test_cases.push_back(ASCIIToUTF16("c")); 461 test_cases.push_back(base::string16(test_string_a)); 462 test_cases.push_back(base::string16(test_string_b)); 463 test_cases.push_back(base::string16(test_string_c)); 464 test_cases.push_back(base::string16(test_string_d)); 465 test_cases.push_back(base::string16(test_string_e)); 466 test_cases.push_back(base::string16(test_string_f)); 467 468 for (size_t i = 0; i < test_cases.size() - 1; ++i) { 469 base::string16 a = test_cases[i]; 470 base::string16 b = test_cases[i + 1]; 471 472 EXPECT_LT(a.compare(b), 0); 473 EXPECT_GT(b.compare(a), 0); 474 EXPECT_EQ(a.compare(a), 0); 475 EXPECT_EQ(b.compare(b), 0); 476 477 std::string encoded_a = WrappedEncodeStringWithLength(a); 478 EXPECT_TRUE(encoded_a.size()); 479 std::string encoded_b = WrappedEncodeStringWithLength(b); 480 EXPECT_TRUE(encoded_a.size()); 481 482 EXPECT_LT(CompareStrings(encoded_a, encoded_b), 0); 483 EXPECT_GT(CompareStrings(encoded_b, encoded_a), 0); 484 EXPECT_EQ(CompareStrings(encoded_a, encoded_a), 0); 485 EXPECT_EQ(CompareStrings(encoded_b, encoded_b), 0); 486 } 487 } 488 489 static std::string WrappedEncodeBinary(std::string value) { 490 std::string buffer; 491 EncodeBinary(value, &buffer); 492 return buffer; 493 } 494 495 TEST(IndexedDBLevelDBCodingTest, EncodeBinary) { 496 const unsigned char binary_data[] = {0x00, 0x01, 0xfe, 0xff}; 497 EXPECT_EQ( 498 static_cast<size_t>(1), 499 WrappedEncodeBinary(std::string(binary_data, binary_data + 0)).size()); 500 EXPECT_EQ( 501 static_cast<size_t>(2), 502 WrappedEncodeBinary(std::string(binary_data, binary_data + 1)).size()); 503 EXPECT_EQ( 504 static_cast<size_t>(5), 505 WrappedEncodeBinary(std::string(binary_data, binary_data + 4)).size()); 506 } 507 508 TEST(IndexedDBLevelDBCodingTest, DecodeBinary) { 509 const unsigned char binary_data[] = { 0x00, 0x01, 0xfe, 0xff }; 510 511 std::vector<std::string> test_cases; 512 test_cases.push_back(std::string(binary_data, binary_data + 0)); 513 test_cases.push_back(std::string(binary_data, binary_data + 1)); 514 test_cases.push_back(std::string(binary_data, binary_data + 4)); 515 516 for (size_t i = 0; i < test_cases.size(); ++i) { 517 std::string value = test_cases[i]; 518 std::string v = WrappedEncodeBinary(value); 519 ASSERT_GT(v.size(), static_cast<size_t>(0)); 520 StringPiece slice(v); 521 std::string result; 522 EXPECT_TRUE(DecodeBinary(&slice, &result)); 523 EXPECT_EQ(value, result); 524 EXPECT_TRUE(slice.empty()); 525 526 slice = StringPiece(&*v.begin(), v.size() - 1); 527 EXPECT_FALSE(DecodeBinary(&slice, &result)); 528 529 slice = StringPiece(&*v.begin(), static_cast<size_t>(0)); 530 EXPECT_FALSE(DecodeBinary(&slice, &result)); 531 532 // Verify decoding at an offset, to detect unaligned memory access. 533 v.insert(v.begin(), static_cast<size_t>(1), static_cast<char>(0)); 534 slice = StringPiece(&*v.begin() + 1, v.size() - 1); 535 EXPECT_TRUE(DecodeBinary(&slice, &result)); 536 EXPECT_EQ(value, result); 537 EXPECT_TRUE(slice.empty()); 538 } 539 } 540 541 static std::string WrappedEncodeDouble(double value) { 542 std::string buffer; 543 EncodeDouble(value, &buffer); 544 return buffer; 545 } 546 547 TEST(IndexedDBLevelDBCodingTest, EncodeDouble) { 548 EXPECT_EQ(static_cast<size_t>(8), WrappedEncodeDouble(0).size()); 549 EXPECT_EQ(static_cast<size_t>(8), WrappedEncodeDouble(3.14).size()); 550 } 551 552 TEST(IndexedDBLevelDBCodingTest, DecodeDouble) { 553 std::vector<double> test_cases; 554 test_cases.push_back(3.14); 555 test_cases.push_back(-3.14); 556 557 for (size_t i = 0; i < test_cases.size(); ++i) { 558 double value = test_cases[i]; 559 std::string v = WrappedEncodeDouble(value); 560 ASSERT_GT(v.size(), static_cast<size_t>(0)); 561 StringPiece slice(v); 562 double result; 563 EXPECT_TRUE(DecodeDouble(&slice, &result)); 564 EXPECT_EQ(value, result); 565 EXPECT_TRUE(slice.empty()); 566 567 slice = StringPiece(&*v.begin(), v.size() - 1); 568 EXPECT_FALSE(DecodeDouble(&slice, &result)); 569 570 slice = StringPiece(&*v.begin(), static_cast<size_t>(0)); 571 EXPECT_FALSE(DecodeDouble(&slice, &result)); 572 573 // Verify decoding at an offset, to detect unaligned memory access. 574 v.insert(v.begin(), static_cast<size_t>(1), static_cast<char>(0)); 575 slice = StringPiece(&*v.begin() + 1, v.size() - 1); 576 EXPECT_TRUE(DecodeDouble(&slice, &result)); 577 EXPECT_EQ(value, result); 578 EXPECT_TRUE(slice.empty()); 579 } 580 } 581 582 TEST(IndexedDBLevelDBCodingTest, EncodeDecodeIDBKey) { 583 IndexedDBKey expected_key; 584 scoped_ptr<IndexedDBKey> decoded_key; 585 std::string v; 586 StringPiece slice; 587 588 std::vector<IndexedDBKey> test_cases; 589 test_cases.push_back(IndexedDBKey(1234, WebIDBKeyTypeNumber)); 590 test_cases.push_back(IndexedDBKey(7890, WebIDBKeyTypeDate)); 591 test_cases.push_back(IndexedDBKey(ASCIIToUTF16("Hello World!"))); 592 test_cases.push_back(IndexedDBKey(std::string("\x01\x02"))); 593 test_cases.push_back(IndexedDBKey(IndexedDBKey::KeyArray())); 594 595 IndexedDBKey::KeyArray array; 596 array.push_back(IndexedDBKey(1234, WebIDBKeyTypeNumber)); 597 array.push_back(IndexedDBKey(7890, WebIDBKeyTypeDate)); 598 array.push_back(IndexedDBKey(ASCIIToUTF16("Hello World!"))); 599 array.push_back(IndexedDBKey(std::string("\x01\x02"))); 600 array.push_back(IndexedDBKey(IndexedDBKey::KeyArray())); 601 test_cases.push_back(IndexedDBKey(array)); 602 603 for (size_t i = 0; i < test_cases.size(); ++i) { 604 expected_key = test_cases[i]; 605 v.clear(); 606 EncodeIDBKey(expected_key, &v); 607 slice = StringPiece(&*v.begin(), v.size()); 608 EXPECT_TRUE(DecodeIDBKey(&slice, &decoded_key)); 609 EXPECT_TRUE(decoded_key->IsEqual(expected_key)); 610 EXPECT_TRUE(slice.empty()); 611 612 slice = StringPiece(&*v.begin(), v.size() - 1); 613 EXPECT_FALSE(DecodeIDBKey(&slice, &decoded_key)); 614 615 slice = StringPiece(&*v.begin(), static_cast<size_t>(0)); 616 EXPECT_FALSE(DecodeIDBKey(&slice, &decoded_key)); 617 } 618 } 619 620 static std::string WrappedEncodeIDBKeyPath(const IndexedDBKeyPath& value) { 621 std::string buffer; 622 EncodeIDBKeyPath(value, &buffer); 623 return buffer; 624 } 625 626 TEST(IndexedDBLevelDBCodingTest, EncodeDecodeIDBKeyPath) { 627 std::vector<IndexedDBKeyPath> key_paths; 628 std::vector<std::string> encoded_paths; 629 630 { 631 key_paths.push_back(IndexedDBKeyPath()); 632 char expected[] = {0, 0, // Header 633 0 // Type is null 634 }; 635 encoded_paths.push_back( 636 std::string(expected, expected + arraysize(expected))); 637 } 638 639 { 640 key_paths.push_back(IndexedDBKeyPath(base::string16())); 641 char expected[] = {0, 0, // Header 642 1, // Type is string 643 0 // Length is 0 644 }; 645 encoded_paths.push_back( 646 std::string(expected, expected + arraysize(expected))); 647 } 648 649 { 650 key_paths.push_back(IndexedDBKeyPath(ASCIIToUTF16("foo"))); 651 char expected[] = {0, 0, // Header 652 1, // Type is string 653 3, 0, 'f', 0, 'o', 0, 'o' // String length 3, UTF-16BE 654 }; 655 encoded_paths.push_back( 656 std::string(expected, expected + arraysize(expected))); 657 } 658 659 { 660 key_paths.push_back(IndexedDBKeyPath(ASCIIToUTF16("foo.bar"))); 661 char expected[] = {0, 0, // Header 662 1, // Type is string 663 7, 0, 'f', 0, 'o', 0, 'o', 0, '.', 0, 'b', 0, 'a', 0, 664 'r' // String length 7, UTF-16BE 665 }; 666 encoded_paths.push_back( 667 std::string(expected, expected + arraysize(expected))); 668 } 669 670 { 671 std::vector<base::string16> array; 672 array.push_back(base::string16()); 673 array.push_back(ASCIIToUTF16("foo")); 674 array.push_back(ASCIIToUTF16("foo.bar")); 675 676 key_paths.push_back(IndexedDBKeyPath(array)); 677 char expected[] = {0, 0, // Header 678 2, 3, // Type is array, length is 3 679 0, // Member 1 (String length 0) 680 3, 0, 'f', 0, 'o', 0, 'o', // Member 2 (String length 3) 681 7, 0, 'f', 0, 'o', 0, 'o', 0, '.', 0, 'b', 0, 'a', 0, 682 'r' // Member 3 (String length 7) 683 }; 684 encoded_paths.push_back( 685 std::string(expected, expected + arraysize(expected))); 686 } 687 688 ASSERT_EQ(key_paths.size(), encoded_paths.size()); 689 for (size_t i = 0; i < key_paths.size(); ++i) { 690 IndexedDBKeyPath key_path = key_paths[i]; 691 std::string encoded = encoded_paths[i]; 692 693 std::string v = WrappedEncodeIDBKeyPath(key_path); 694 EXPECT_EQ(encoded, v); 695 696 StringPiece slice(encoded); 697 IndexedDBKeyPath decoded; 698 EXPECT_TRUE(DecodeIDBKeyPath(&slice, &decoded)); 699 EXPECT_EQ(key_path, decoded); 700 EXPECT_TRUE(slice.empty()); 701 } 702 } 703 704 TEST(IndexedDBLevelDBCodingTest, DecodeLegacyIDBKeyPath) { 705 // Legacy encoding of string key paths. 706 std::vector<IndexedDBKeyPath> key_paths; 707 std::vector<std::string> encoded_paths; 708 709 { 710 key_paths.push_back(IndexedDBKeyPath(base::string16())); 711 encoded_paths.push_back(std::string()); 712 } 713 { 714 key_paths.push_back(IndexedDBKeyPath(ASCIIToUTF16("foo"))); 715 char expected[] = {0, 'f', 0, 'o', 0, 'o'}; 716 encoded_paths.push_back(std::string(expected, arraysize(expected))); 717 } 718 { 719 key_paths.push_back(IndexedDBKeyPath(ASCIIToUTF16("foo.bar"))); 720 char expected[] = {0, 'f', 0, 'o', 0, 'o', 0, '.', 0, 'b', 0, 'a', 0, 'r'}; 721 encoded_paths.push_back(std::string(expected, arraysize(expected))); 722 } 723 724 ASSERT_EQ(key_paths.size(), encoded_paths.size()); 725 for (size_t i = 0; i < key_paths.size(); ++i) { 726 IndexedDBKeyPath key_path = key_paths[i]; 727 std::string encoded = encoded_paths[i]; 728 729 StringPiece slice(encoded); 730 IndexedDBKeyPath decoded; 731 EXPECT_TRUE(DecodeIDBKeyPath(&slice, &decoded)); 732 EXPECT_EQ(key_path, decoded); 733 EXPECT_TRUE(slice.empty()); 734 } 735 } 736 737 TEST(IndexedDBLevelDBCodingTest, ExtractAndCompareIDBKeys) { 738 std::vector<IndexedDBKey> keys; 739 740 keys.push_back(IndexedDBKey(-10, WebIDBKeyTypeNumber)); 741 keys.push_back(IndexedDBKey(0, WebIDBKeyTypeNumber)); 742 keys.push_back(IndexedDBKey(3.14, WebIDBKeyTypeNumber)); 743 744 keys.push_back(IndexedDBKey(0, WebIDBKeyTypeDate)); 745 keys.push_back(IndexedDBKey(100, WebIDBKeyTypeDate)); 746 keys.push_back(IndexedDBKey(100000, WebIDBKeyTypeDate)); 747 748 keys.push_back(IndexedDBKey(ASCIIToUTF16(""))); 749 keys.push_back(IndexedDBKey(ASCIIToUTF16("a"))); 750 keys.push_back(IndexedDBKey(ASCIIToUTF16("b"))); 751 keys.push_back(IndexedDBKey(ASCIIToUTF16("baaa"))); 752 keys.push_back(IndexedDBKey(ASCIIToUTF16("baab"))); 753 keys.push_back(IndexedDBKey(ASCIIToUTF16("c"))); 754 755 keys.push_back(IndexedDBKey(std::string())); 756 keys.push_back(IndexedDBKey(std::string("\x01"))); 757 keys.push_back(IndexedDBKey(std::string("\x01\x01"))); 758 keys.push_back(IndexedDBKey(std::string("\x01\x02"))); 759 keys.push_back(IndexedDBKey(std::string("\x02"))); 760 keys.push_back(IndexedDBKey(std::string("\x02\x01"))); 761 keys.push_back(IndexedDBKey(std::string("\x02\x02"))); 762 keys.push_back(IndexedDBKey(std::string("\xff"))); 763 764 keys.push_back(CreateArrayIDBKey()); 765 keys.push_back(CreateArrayIDBKey(IndexedDBKey(0, WebIDBKeyTypeNumber))); 766 keys.push_back(CreateArrayIDBKey(IndexedDBKey(0, WebIDBKeyTypeNumber), 767 IndexedDBKey(3.14, WebIDBKeyTypeNumber))); 768 keys.push_back(CreateArrayIDBKey(IndexedDBKey(0, WebIDBKeyTypeDate))); 769 keys.push_back(CreateArrayIDBKey(IndexedDBKey(0, WebIDBKeyTypeDate), 770 IndexedDBKey(0, WebIDBKeyTypeDate))); 771 keys.push_back(CreateArrayIDBKey(IndexedDBKey(ASCIIToUTF16("")))); 772 keys.push_back(CreateArrayIDBKey(IndexedDBKey(ASCIIToUTF16("")), 773 IndexedDBKey(ASCIIToUTF16("a")))); 774 keys.push_back(CreateArrayIDBKey(CreateArrayIDBKey())); 775 keys.push_back(CreateArrayIDBKey(CreateArrayIDBKey(), CreateArrayIDBKey())); 776 keys.push_back(CreateArrayIDBKey(CreateArrayIDBKey(CreateArrayIDBKey()))); 777 keys.push_back(CreateArrayIDBKey( 778 CreateArrayIDBKey(CreateArrayIDBKey(CreateArrayIDBKey())))); 779 780 for (size_t i = 0; i < keys.size() - 1; ++i) { 781 const IndexedDBKey& key_a = keys[i]; 782 const IndexedDBKey& key_b = keys[i + 1]; 783 784 EXPECT_TRUE(key_a.IsLessThan(key_b)); 785 786 std::string encoded_a; 787 EncodeIDBKey(key_a, &encoded_a); 788 EXPECT_TRUE(encoded_a.size()); 789 std::string encoded_b; 790 EncodeIDBKey(key_b, &encoded_b); 791 EXPECT_TRUE(encoded_b.size()); 792 793 std::string extracted_a; 794 std::string extracted_b; 795 StringPiece slice; 796 797 slice = StringPiece(encoded_a); 798 EXPECT_TRUE(ExtractEncodedIDBKey(&slice, &extracted_a)); 799 EXPECT_TRUE(slice.empty()); 800 EXPECT_EQ(encoded_a, extracted_a); 801 802 slice = StringPiece(encoded_b); 803 EXPECT_TRUE(ExtractEncodedIDBKey(&slice, &extracted_b)); 804 EXPECT_TRUE(slice.empty()); 805 EXPECT_EQ(encoded_b, extracted_b); 806 807 EXPECT_LT(CompareKeys(extracted_a, extracted_b), 0); 808 EXPECT_GT(CompareKeys(extracted_b, extracted_a), 0); 809 EXPECT_EQ(CompareKeys(extracted_a, extracted_a), 0); 810 EXPECT_EQ(CompareKeys(extracted_b, extracted_b), 0); 811 812 slice = StringPiece(&*encoded_a.begin(), encoded_a.size() - 1); 813 EXPECT_FALSE(ExtractEncodedIDBKey(&slice, &extracted_a)); 814 } 815 } 816 817 TEST(IndexedDBLevelDBCodingTest, ComparisonTest) { 818 std::vector<std::string> keys; 819 keys.push_back(SchemaVersionKey::Encode()); 820 keys.push_back(MaxDatabaseIdKey::Encode()); 821 keys.push_back(DatabaseFreeListKey::Encode(0)); 822 keys.push_back(DatabaseFreeListKey::EncodeMaxKey()); 823 keys.push_back(DatabaseNameKey::Encode("", ASCIIToUTF16(""))); 824 keys.push_back(DatabaseNameKey::Encode("", ASCIIToUTF16("a"))); 825 keys.push_back(DatabaseNameKey::Encode("a", ASCIIToUTF16("a"))); 826 keys.push_back( 827 DatabaseMetaDataKey::Encode(1, DatabaseMetaDataKey::ORIGIN_NAME)); 828 keys.push_back( 829 DatabaseMetaDataKey::Encode(1, DatabaseMetaDataKey::DATABASE_NAME)); 830 keys.push_back( 831 DatabaseMetaDataKey::Encode(1, DatabaseMetaDataKey::USER_VERSION)); 832 keys.push_back( 833 DatabaseMetaDataKey::Encode(1, DatabaseMetaDataKey::MAX_OBJECT_STORE_ID)); 834 keys.push_back( 835 DatabaseMetaDataKey::Encode(1, DatabaseMetaDataKey::USER_INT_VERSION)); 836 keys.push_back( 837 ObjectStoreMetaDataKey::Encode(1, 1, ObjectStoreMetaDataKey::NAME)); 838 keys.push_back( 839 ObjectStoreMetaDataKey::Encode(1, 1, ObjectStoreMetaDataKey::KEY_PATH)); 840 keys.push_back(ObjectStoreMetaDataKey::Encode( 841 1, 1, ObjectStoreMetaDataKey::AUTO_INCREMENT)); 842 keys.push_back( 843 ObjectStoreMetaDataKey::Encode(1, 1, ObjectStoreMetaDataKey::EVICTABLE)); 844 keys.push_back(ObjectStoreMetaDataKey::Encode( 845 1, 1, ObjectStoreMetaDataKey::LAST_VERSION)); 846 keys.push_back(ObjectStoreMetaDataKey::Encode( 847 1, 1, ObjectStoreMetaDataKey::MAX_INDEX_ID)); 848 keys.push_back(ObjectStoreMetaDataKey::Encode( 849 1, 1, ObjectStoreMetaDataKey::HAS_KEY_PATH)); 850 keys.push_back(ObjectStoreMetaDataKey::Encode( 851 1, 1, ObjectStoreMetaDataKey::KEY_GENERATOR_CURRENT_NUMBER)); 852 keys.push_back(ObjectStoreMetaDataKey::EncodeMaxKey(1, 1)); 853 keys.push_back(ObjectStoreMetaDataKey::EncodeMaxKey(1, 2)); 854 keys.push_back(ObjectStoreMetaDataKey::EncodeMaxKey(1)); 855 keys.push_back(IndexMetaDataKey::Encode(1, 1, 30, IndexMetaDataKey::NAME)); 856 keys.push_back(IndexMetaDataKey::Encode(1, 1, 30, IndexMetaDataKey::UNIQUE)); 857 keys.push_back( 858 IndexMetaDataKey::Encode(1, 1, 30, IndexMetaDataKey::KEY_PATH)); 859 keys.push_back( 860 IndexMetaDataKey::Encode(1, 1, 30, IndexMetaDataKey::MULTI_ENTRY)); 861 keys.push_back(IndexMetaDataKey::Encode(1, 1, 31, 0)); 862 keys.push_back(IndexMetaDataKey::Encode(1, 1, 31, 1)); 863 keys.push_back(IndexMetaDataKey::EncodeMaxKey(1, 1, 31)); 864 keys.push_back(IndexMetaDataKey::EncodeMaxKey(1, 1, 32)); 865 keys.push_back(IndexMetaDataKey::EncodeMaxKey(1, 1)); 866 keys.push_back(IndexMetaDataKey::EncodeMaxKey(1, 2)); 867 keys.push_back(ObjectStoreFreeListKey::Encode(1, 1)); 868 keys.push_back(ObjectStoreFreeListKey::EncodeMaxKey(1)); 869 keys.push_back(IndexFreeListKey::Encode(1, 1, kMinimumIndexId)); 870 keys.push_back(IndexFreeListKey::EncodeMaxKey(1, 1)); 871 keys.push_back(IndexFreeListKey::Encode(1, 2, kMinimumIndexId)); 872 keys.push_back(IndexFreeListKey::EncodeMaxKey(1, 2)); 873 keys.push_back(ObjectStoreNamesKey::Encode(1, ASCIIToUTF16(""))); 874 keys.push_back(ObjectStoreNamesKey::Encode(1, ASCIIToUTF16("a"))); 875 keys.push_back(IndexNamesKey::Encode(1, 1, ASCIIToUTF16(""))); 876 keys.push_back(IndexNamesKey::Encode(1, 1, ASCIIToUTF16("a"))); 877 keys.push_back(IndexNamesKey::Encode(1, 2, ASCIIToUTF16("a"))); 878 keys.push_back(ObjectStoreDataKey::Encode(1, 1, std::string())); 879 keys.push_back(ObjectStoreDataKey::Encode(1, 1, MinIDBKey())); 880 keys.push_back(ObjectStoreDataKey::Encode(1, 1, MaxIDBKey())); 881 keys.push_back(ExistsEntryKey::Encode(1, 1, std::string())); 882 keys.push_back(ExistsEntryKey::Encode(1, 1, MinIDBKey())); 883 keys.push_back(ExistsEntryKey::Encode(1, 1, MaxIDBKey())); 884 keys.push_back(IndexDataKey::Encode(1, 1, 30, MinIDBKey(), std::string(), 0)); 885 keys.push_back(IndexDataKey::Encode(1, 1, 30, MinIDBKey(), MinIDBKey(), 0)); 886 keys.push_back(IndexDataKey::Encode(1, 1, 30, MinIDBKey(), MinIDBKey(), 1)); 887 keys.push_back(IndexDataKey::Encode(1, 1, 30, MinIDBKey(), MaxIDBKey(), 0)); 888 keys.push_back(IndexDataKey::Encode(1, 1, 30, MinIDBKey(), MaxIDBKey(), 1)); 889 keys.push_back(IndexDataKey::Encode(1, 1, 30, MaxIDBKey(), MinIDBKey(), 0)); 890 keys.push_back(IndexDataKey::Encode(1, 1, 30, MaxIDBKey(), MinIDBKey(), 1)); 891 keys.push_back(IndexDataKey::Encode(1, 1, 30, MaxIDBKey(), MaxIDBKey(), 0)); 892 keys.push_back(IndexDataKey::Encode(1, 1, 30, MaxIDBKey(), MaxIDBKey(), 1)); 893 keys.push_back(IndexDataKey::Encode(1, 1, 31, MinIDBKey(), MinIDBKey(), 0)); 894 keys.push_back(IndexDataKey::Encode(1, 2, 30, MinIDBKey(), MinIDBKey(), 0)); 895 keys.push_back( 896 IndexDataKey::EncodeMaxKey(1, 2, std::numeric_limits<int32>::max() - 1)); 897 898 for (size_t i = 0; i < keys.size(); ++i) { 899 EXPECT_EQ(Compare(keys[i], keys[i], false), 0); 900 901 for (size_t j = i + 1; j < keys.size(); ++j) { 902 EXPECT_LT(Compare(keys[i], keys[j], false), 0); 903 EXPECT_GT(Compare(keys[j], keys[i], false), 0); 904 } 905 } 906 } 907 908 TEST(IndexedDBLevelDBCodingTest, EncodeVarIntVSEncodeByteTest) { 909 std::vector<unsigned char> test_cases; 910 test_cases.push_back(0); 911 test_cases.push_back(1); 912 test_cases.push_back(127); 913 914 for (size_t i = 0; i < test_cases.size(); ++i) { 915 unsigned char n = test_cases[i]; 916 917 std::string vA = WrappedEncodeByte(n); 918 std::string vB = WrappedEncodeVarInt(static_cast<int64>(n)); 919 920 EXPECT_EQ(vA.size(), vB.size()); 921 EXPECT_EQ(*vA.begin(), *vB.begin()); 922 } 923 } 924 925 } // namespace 926 927 } // namespace content 928