Coverage Report

Created: 2025-08-29 06:44

/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
}