Coverage Report

Created: 2023-06-07 06:33

/src/uri_parse_fuzzer.cc
Line
Count
Source (jump to first uncovered line)
1
// Copyright 2020 Google LLC
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
// you may not use this file except in compliance with the License.
5
// You may obtain a copy of the License at
6
//
7
//      http://www.apache.org/licenses/LICENSE-2.0
8
//
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
14
15
#include <cstddef>
16
#include <cstring>
17
#include <string>
18
#include <vector>
19
#include <fuzzer/FuzzedDataProvider.h>
20
21
using std::string;
22
#include "uriparser/include/uriparser/Uri.h"
23
#include "uriparser/include/uriparser/UriIp4.h"
24
25
class UriParserA {
26
 public:
27
21.0k
  UriParserA() { memset((void *)&uri_, 0, sizeof(uri_)); }
28
21.0k
  ~UriParserA() { uriFreeUriMembersA(&uri_); }
29
30
21.0k
  UriUriA *get_mutable_uri() { return &uri_; }
31
0
  UriUriA *get_uri() const { return const_cast<UriUriA *>(&uri_); }
32
33
 private:
34
  UriUriA uri_;
35
};
36
37
21.7k
void Escapes(const string &uri) {
38
21.7k
  const char *first = uri.c_str();
39
  // A new line char takes 6 char to encode.
40
  // Use a vector to make a C string.
41
21.7k
  std::vector<char> buf1(uri.size() * 6 + 1);
42
21.7k
  std::vector<char> buf2(uri.size() * 3 + 1);
43
44
21.7k
  char *result;
45
21.7k
  result = uriEscapeA(first, &buf1[0], URI_TRUE, URI_TRUE);
46
21.7k
  result = uriEscapeA(first, &buf1[0], URI_FALSE, URI_TRUE);
47
21.7k
  if (buf1.data()) uriUnescapeInPlaceA(&buf1[0]);
48
49
21.7k
  result = uriEscapeA(first, &buf2[0], URI_TRUE, URI_FALSE);
50
21.7k
  result = uriEscapeA(first, &buf2[0], URI_FALSE, URI_FALSE);
51
21.7k
  if (buf2.data()) uriUnescapeInPlaceA(&buf2[0]);
52
21.7k
}
53
54
21.7k
void FileNames(const string &uri) {
55
21.7k
  const size_t size = 8 + 3 * uri.size() + 1;
56
21.7k
  std::vector<char> buf(size);
57
58
21.7k
  uriUnixFilenameToUriStringA(uri.c_str(), &buf[0]);
59
21.7k
  uriWindowsFilenameToUriStringA(uri.c_str(), &buf[0]);
60
21.7k
  uriUriStringToUnixFilenameA(uri.c_str(), &buf[0]);
61
21.7k
  uriUriStringToWindowsFilenameA(uri.c_str(), &buf[0]);
62
21.7k
}
63
64
int uriParseIpFourAddressA(unsigned char *octetOutput, const char *first,
65
                           const char *afterLast);
66
67
21.7k
void Ipv4(const string &s) {
68
21.7k
  const char *cstr = s.c_str();
69
21.7k
  unsigned char result[4] = {};
70
21.7k
  uriParseIpFourAddressA(result, cstr, &cstr[s.size()]);
71
21.7k
}
72
73
10.8k
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
74
75
10.8k
  FuzzedDataProvider stream(data, size);
76
10.8k
  bool domainRelative = stream.ConsumeBool();
77
10.8k
  size_t uriSize = stream.remaining_bytes() / 2;
78
79
10.8k
  const string uri1 = stream.ConsumeBytesAsString(uriSize);
80
10.8k
  const string uri2 = stream.ConsumeRemainingBytesAsString();
81
82
10.8k
  Escapes(uri1);
83
10.8k
  Escapes(uri2);
84
85
10.8k
  FileNames(uri1);
86
10.8k
  FileNames(uri2);
87
88
10.8k
  Ipv4(uri1);
89
10.8k
  Ipv4(uri2);
90
91
10.8k
  UriParserA parser1;
92
10.8k
  UriParserStateA state1;
93
10.8k
  state1.uri = parser1.get_mutable_uri();
94
10.8k
  if (uriParseUriA(&state1, uri1.c_str()) != URI_SUCCESS)
95
619
    return 0;
96
97
10.2k
  char buf[1024 * 8] = {0};
98
10.2k
  int written = 0;
99
10.2k
  uriToStringA(buf, state1.uri, sizeof(buf), &written);
100
101
10.2k
  UriParserA parser2;
102
10.2k
  UriParserStateA state2;
103
10.2k
  state2.uri = parser2.get_mutable_uri();
104
10.2k
  if (uriParseUriA(&state2, uri2.c_str()) != URI_SUCCESS)
105
3.05k
    return 0;
106
107
7.18k
  uriEqualsUriA(state1.uri, state2.uri);
108
109
7.18k
  uriNormalizeSyntaxA(state1.uri);
110
111
7.18k
  UriUriA absUri;
112
7.18k
  uriAddBaseUriA(&absUri, state1.uri, state2.uri);
113
7.18k
  uriFreeUriMembersA(&absUri);
114
115
7.18k
  UriUriA relUri;
116
7.18k
  uriRemoveBaseUriA(&relUri, state1.uri, state2.uri, domainRelative);
117
7.18k
  uriFreeUriMembersA(&relUri);
118
119
7.18k
  return 0;
120
10.2k
}