121 lines
		
	
	
		
			3.4 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			121 lines
		
	
	
		
			3.4 KiB
		
	
	
	
		
			C++
		
	
	
	
// 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;
 | 
						|
}
 |