1 // Copyright 2019 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 <stddef.h>
6 #include <stdint.h>
7 
8 #include <fuzzer/FuzzedDataProvider.h>
9 
10 #include "base/strings/utf_string_conversions.h"
11 #include "content/browser/indexed_db/indexed_db_leveldb_coding.h"
12 #include "third_party/blink/public/common/indexeddb/indexeddb_key_path.h"
13 
14 using blink::IndexedDBKeyPath;
15 
GetKeyPath(FuzzedDataProvider * fuzzed_data)16 IndexedDBKeyPath GetKeyPath(FuzzedDataProvider* fuzzed_data) {
17   // If there is no more data to use, return an empty key path.
18   if (fuzzed_data->remaining_bytes() < 1)
19     return IndexedDBKeyPath();
20 
21   // Consume sizeof(size_t) bytes to determine the size of the vector of strings
22   // to use for the IndexedDBKeyPath.
23   auto vector_size = fuzzed_data->ConsumeIntegral<size_t>();
24 
25   if (vector_size == 0) {
26     return IndexedDBKeyPath();
27   } else if (vector_size == 1) {
28     // Consume all of |fuzzed_data| to create an IndexedDBKeyPath.
29     auto str16 =
30         base::UTF8ToUTF16(fuzzed_data->ConsumeRemainingBytesAsString());
31     return IndexedDBKeyPath(str16);
32   }
33 
34   // Create and add string16s to |paths| until |vector_size| is reached or the
35   // end of |data| is reached.
36   std::vector<base::string16> paths;
37   for (size_t i = 0; i < vector_size && fuzzed_data->remaining_bytes() > 0;
38        ++i) {
39     // Consume sizeof(size_t) bytes to determine the size of the string to
40     // create.
41     size_t str_size = fuzzed_data->ConsumeIntegral<size_t>();
42 
43     auto str16 = base::UTF8ToUTF16(fuzzed_data->ConsumeBytesAsString(str_size));
44     paths.push_back(str16);
45   }
46   return IndexedDBKeyPath(paths);
47 }
48 
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)49 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
50   FuzzedDataProvider fuzzed_data(data, size);
51   IndexedDBKeyPath key_path = GetKeyPath(&fuzzed_data);
52   std::string result;
53   content::EncodeIDBKeyPath(key_path, &result);
54 
55   // Ensure that |result| can be decoded back into the original key path.
56   IndexedDBKeyPath decoded_key_path;
57   auto result_str_piece = base::StringPiece(result);
58   ignore_result(
59       content::DecodeIDBKeyPath(&result_str_piece, &decoded_key_path));
60   assert(decoded_key_path == key_path);
61   return 0;
62 }
63