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