aboutsummaryrefslogtreecommitdiffhomepage
path: root/projects/uriparser
diff options
context:
space:
mode:
authorGravatar Ravi Jotwani <rjotwani@google.com>2020-07-20 16:50:20 -0700
committerGravatar GitHub <noreply@github.com>2020-07-20 16:50:20 -0700
commit36e6fa39fed738edff6bc2c6a1b03530c03576ed (patch)
tree46da7db72d3dc3b941656fd983f84c3af81bd740 /projects/uriparser
parent283447224d8a295027fd20fb5ac6962cc95dc55b (diff)
[uriparser] Add new fuzzers (#4134)
* added new fuzzer * added new fuzzer * removed commented code * add license header for uri_parse_fuzzer * get values from FuzzedDataProvider, awaiting fuzz targets for FileNames and Ipv4 in parse_fuzzer * build working * fixed size mismatch, used better consumption function for remaining input * reduced maxSize for uri_dissect_query_malloc_fuzzer * added missing fuzz targets, removed unnecessary import * removed unused include, changed instances of std::string to string, removed ToVector, added checks, and removed usage of FuzzedDataProvider in uri_dissect_query_malloc_fuzzer * fixed vector issue in uri_parse_fuzzer * added explicit value checks, removed Yoda comparisons
Diffstat (limited to 'projects/uriparser')
-rw-r--r--projects/uriparser/uri_dissect_query_malloc_fuzzer.cc58
-rw-r--r--projects/uriparser/uri_parse_fuzzer.cc120
2 files changed, 178 insertions, 0 deletions
diff --git a/projects/uriparser/uri_dissect_query_malloc_fuzzer.cc b/projects/uriparser/uri_dissect_query_malloc_fuzzer.cc
new file mode 100644
index 00000000..32e81555
--- /dev/null
+++ b/projects/uriparser/uri_dissect_query_malloc_fuzzer.cc
@@ -0,0 +1,58 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Fuzz UriQuery.c:
+// uriDissectQueryMallocA
+// uriComposeQueryA
+
+#include <cstddef>
+#include <cstdint>
+#include <string>
+#include <utility>
+#include <vector>
+
+using std::string;
+#include "uriparser/include/uriparser/Uri.h"
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
+
+ const string query(reinterpret_cast<const char *>(data), size);
+
+ UriQueryListA *query_list = nullptr;
+ int item_count = -1;
+
+ const char *query_start = query.c_str();
+ const char *query_end = query_start + size;
+
+ // Break a query like "a=b&2=3" into key/value pairs.
+ int result =
+ uriDissectQueryMallocA(&query_list, &item_count, query_start, query_end);
+
+ if (query_list == nullptr || result != URI_SUCCESS || item_count < 0)
+ return 0;
+
+ int chars_required;
+ if (uriComposeQueryCharsRequiredA(query_list, &chars_required) != URI_SUCCESS)
+ return 0;
+
+ std::vector<char> buf(chars_required, 0);
+ int written = -1;
+ char *dest = &buf[0];
+ // Reverse the process of uriDissectQueryMallocA.
+ result = uriComposeQueryA(dest, query_list, chars_required, &written);
+
+ uriFreeQueryListA(query_list);
+
+ return 0;
+}
diff --git a/projects/uriparser/uri_parse_fuzzer.cc b/projects/uriparser/uri_parse_fuzzer.cc
new file mode 100644
index 00000000..4eca6698
--- /dev/null
+++ b/projects/uriparser/uri_parse_fuzzer.cc
@@ -0,0 +1,120 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include <cstddef>
+#include <cstring>
+#include <string>
+#include <vector>
+#include <fuzzer/FuzzedDataProvider.h>
+
+using std::string;
+#include "uriparser/include/uriparser/Uri.h"
+#include "uriparser/include/uriparser/UriIp4.h"
+
+class UriParserA {
+ public:
+ UriParserA() { memset((void *)&uri_, 0, sizeof(uri_)); }
+ ~UriParserA() { uriFreeUriMembersA(&uri_); }
+
+ UriUriA *get_mutable_uri() { return &uri_; }
+ UriUriA *get_uri() const { return const_cast<UriUriA *>(&uri_); }
+
+ private:
+ UriUriA uri_;
+};
+
+void Escapes(const string &uri) {
+ const char *first = uri.c_str();
+ // A new line char takes 6 char to encode.
+ // Use a vector to make a C string.
+ std::vector<char> buf1(uri.size() * 6 + 1);
+ std::vector<char> buf2(uri.size() * 3 + 1);
+
+ char *result;
+ result = uriEscapeA(first, &buf1[0], URI_TRUE, URI_TRUE);
+ result = uriEscapeA(first, &buf1[0], URI_FALSE, URI_TRUE);
+ if (buf1.data()) uriUnescapeInPlaceA(&buf1[0]);
+
+ result = uriEscapeA(first, &buf2[0], URI_TRUE, URI_FALSE);
+ result = uriEscapeA(first, &buf2[0], URI_FALSE, URI_FALSE);
+ if (buf2.data()) uriUnescapeInPlaceA(&buf2[0]);
+}
+
+void FileNames(const string &uri) {
+ const size_t size = 8 + 3 * uri.size() + 1;
+ std::vector<char> buf(size);
+
+ uriUnixFilenameToUriStringA(uri.c_str(), &buf[0]);
+ uriWindowsFilenameToUriStringA(uri.c_str(), &buf[0]);
+ uriUriStringToUnixFilenameA(uri.c_str(), &buf[0]);
+ uriUriStringToWindowsFilenameA(uri.c_str(), &buf[0]);
+}
+
+int uriParseIpFourAddressA(unsigned char *octetOutput, const char *first,
+ const char *afterLast);
+
+void Ipv4(const string &s) {
+ const char *cstr = s.c_str();
+ unsigned char result[4] = {};
+ uriParseIpFourAddressA(result, cstr, &cstr[s.size()]);
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
+
+ FuzzedDataProvider stream(data, size);
+ bool domainRelative = stream.ConsumeBool();
+ size_t uriSize = stream.remaining_bytes() / 2;
+
+ const string uri1 = stream.ConsumeBytesAsString(uriSize);
+ const string uri2 = stream.ConsumeRemainingBytesAsString();
+
+ Escapes(uri1);
+ Escapes(uri2);
+
+ FileNames(uri1);
+ FileNames(uri2);
+
+ Ipv4(uri1);
+ Ipv4(uri2);
+
+ UriParserA parser1;
+ UriParserStateA state1;
+ state1.uri = parser1.get_mutable_uri();
+ if (uriParseUriA(&state1, uri1.c_str()) != URI_SUCCESS)
+ return 0;
+
+ char buf[1024 * 8] = {0};
+ int written = 0;
+ uriToStringA(buf, state1.uri, sizeof(buf), &written);
+
+ UriParserA parser2;
+ UriParserStateA state2;
+ state2.uri = parser2.get_mutable_uri();
+ if (uriParseUriA(&state2, uri2.c_str()) != URI_SUCCESS)
+ return 0;
+
+ uriEqualsUriA(state1.uri, state2.uri);
+
+ uriNormalizeSyntaxA(state1.uri);
+
+ UriUriA absUri;
+ uriAddBaseUriA(&absUri, state1.uri, state2.uri);
+ uriFreeUriMembersA(&absUri);
+
+ UriUriA relUri;
+ uriRemoveBaseUriA(&relUri, state1.uri, state2.uri, domainRelative);
+ uriFreeUriMembersA(&relUri);
+
+ return 0;
+}