/src/s2geometry/src/s2_fuzzer.cc
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | # Copyright 2020 Google Inc. |
3 | | # |
4 | | # Licensed under the Apache License, Version 2.0 (the "License"); |
5 | | # you may not use this file except in compliance with the License. |
6 | | # You may obtain a copy of the License at |
7 | | # |
8 | | # http://www.apache.org/licenses/LICENSE-2.0 |
9 | | # |
10 | | # Unless required by applicable law or agreed to in writing, software |
11 | | # distributed under the License is distributed on an "AS IS" BASIS, |
12 | | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
13 | | # See the License for the specific language governing permissions and |
14 | | # limitations under the License. |
15 | | # |
16 | | ################################################################################ |
17 | | */ |
18 | | |
19 | | #include <stdint.h> |
20 | | #include <stdlib.h> |
21 | | #include <string.h> |
22 | | |
23 | | #include "absl/strings/str_split.h" |
24 | | #include "absl/strings/string_view.h" |
25 | | |
26 | | #include "s2/s2shape_index.h" |
27 | | #include "s2/s2text_format.h" |
28 | | |
29 | | // A string-splitter used to help validate the string |
30 | | // passed to s2 |
31 | | static std::vector<absl::string_view> SplitString(absl::string_view str, |
32 | 4.93k | char separator) { |
33 | 4.93k | std::vector<absl::string_view> result = |
34 | 4.93k | absl::StrSplit(str, separator, absl::SkipWhitespace()); |
35 | 14.6k | for (auto &e : result) { |
36 | 14.6k | e = absl::StripAsciiWhitespace(e); |
37 | 14.6k | } |
38 | 4.93k | return result; |
39 | 4.93k | } |
40 | | |
41 | | // Null-terminates the fuzzers input test case |
42 | 4.95k | char *null_terminated(const uint8_t *data, size_t size) { |
43 | 4.95k | char *new_str = (char *)malloc(size + 1); |
44 | 4.95k | if (new_str == NULL) { |
45 | 0 | return 0; |
46 | 0 | } |
47 | 4.95k | memcpy(new_str, data, size); |
48 | 4.95k | new_str[size] = '\0'; |
49 | 4.95k | return new_str; |
50 | 4.95k | } |
51 | | |
52 | | // Do a bit of validation that is also done by s2 |
53 | | // We do them here since s2 would terminate if they |
54 | | // would return false inside s2. |
55 | 4.95k | bool isValidFormat(char *nt_string, size_t size) { |
56 | 4.95k | int hash_count = 0; |
57 | 67.4M | for (int i = 0; i < size; i++) { |
58 | 67.4M | if (nt_string[i] == 35) { |
59 | 10.0k | hash_count++; |
60 | 10.0k | } |
61 | 67.4M | } |
62 | 4.95k | if (hash_count != 2) { |
63 | 19 | return false; |
64 | 19 | } |
65 | | |
66 | 4.93k | std::vector<absl::string_view> strs = SplitString(nt_string, '#'); |
67 | 4.93k | size_t strs_size = strs.size(); |
68 | 4.93k | if (strs.size() != 3) { |
69 | 61 | return false; |
70 | 61 | } |
71 | | |
72 | 4.87k | auto index1 = absl::make_unique<MutableS2ShapeIndex>(); |
73 | 4.87k | if (s2textformat::MakeIndex(nt_string, &index1) == false) { |
74 | 3.23k | return false; |
75 | 3.23k | } |
76 | 1.64k | return true; |
77 | 4.87k | } |
78 | | |
79 | 4.95k | extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { |
80 | | |
81 | 4.95k | if (size < 5) { |
82 | 4 | return 0; |
83 | 4 | } |
84 | | |
85 | 4.95k | char *nt_string = null_terminated(data, size); |
86 | 4.95k | if (nt_string == NULL) { |
87 | 0 | return 0; |
88 | 0 | } |
89 | 4.95k | if (isValidFormat(nt_string, size)) { |
90 | 1.64k | auto index = absl::make_unique<MutableS2ShapeIndex>(); |
91 | 1.64k | s2textformat::MakeIndex(nt_string, &index); |
92 | 1.64k | } |
93 | 4.95k | free(nt_string); |
94 | 4.95k | return 0; |
95 | 4.95k | } |