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