/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
#include <iostream>
#include "FuzzingInterface.h"
#include "nsComponentManagerUtils.h"
#include "nsCOMPtr.h"
#include "nsIURL.h"
#include "nsIStandardURL.h"
#include "nsIURIMutator.h"
#include "nsNetUtil.h"
#include "nsNetCID.h"
#include "nsPrintfCString.h"
#include "nsString.h"
#include "mozilla/Encoding.h"
#include "mozilla/Span.h"
#include "mozilla/Unused.h"
template <
typename T>
T get_numeric(
char** buf, size_t* size) {
if (
sizeof(T) > *size) {
return 0;
}
T* iptr =
reinterpret_cast<T*>(*buf);
*buf +=
sizeof(T);
*size -=
sizeof(T);
return *iptr;
}
nsAutoCString get_string(
char** buf, size_t* size) {
uint8_t len = get_numeric<uint8_t>(buf, size);
if (len > *size) {
len =
static_cast<uint8_t>(*size);
}
nsAutoCString str(*buf, len);
*buf += len;
*size -= len;
return str;
}
const char* charsets[] = {
"Big5",
"EUC-JP",
"EUC-KR",
"gb18030",
"gbk",
"IBM866",
"ISO-2022-JP",
"ISO-8859-10",
"ISO-8859-13",
"ISO-8859-14",
"ISO-8859-15",
"ISO-8859-16",
"ISO-8859-2",
"ISO-8859-3",
"ISO-8859-4",
"ISO-8859-5",
"ISO-8859-6",
"ISO-8859-7",
"ISO-8859-8",
"ISO-8859-8-I",
"KOI8-R",
"KOI8-U",
"macintosh",
"replacement",
"Shift_JIS",
"UTF-16BE",
"UTF-16LE",
"UTF-8",
"windows-1250",
"windows-1251",
"windows-1252",
"windows-1253",
"windows-1254",
"windows-1255",
"windows-1256",
"windows-1257",
"windows-1258",
"windows-874",
"x-mac-cyrillic",
"x-user-defined"};
static int FuzzingRunURIParser(
const uint8_t* data, size_t size) {
char* buf = (
char*)data;
nsCOMPtr<nsIURI> uri;
nsAutoCString spec = get_string(&buf, &size);
nsresult rv = NS_NewURI(getter_AddRefs(uri), spec);
if (NS_FAILED(rv)) {
return 0;
}
uint8_t iters = get_numeric<uint8_t>(&buf, &size);
for (
int i = 0; i < iters; i++) {
if (get_numeric<uint8_t>(&buf, &size) % 25 != 0) {
NS_MutateURI mutator(uri);
nsAutoCString acdata = get_string(&buf, &size);
switch (get_numeric<uint8_t>(&buf, &size) % 12) {
default:
mutator.SetSpec(acdata);
break;
case 1:
mutator.SetScheme(acdata);
break;
case 2:
mutator.SetUserPass(acdata);
break;
case 3:
mutator.SetUsername(acdata);
break;
case 4:
mutator.SetPassword(acdata);
break;
case 5:
mutator.SetHostPort(acdata);
break;
case 6:
// Called via SetHostPort
mutator.SetHost(acdata);
break;
case 7:
// Called via multiple paths
mutator.SetPathQueryRef(acdata);
break;
case 8:
mutator.SetRef(acdata);
break;
case 9:
mutator.SetFilePath(acdata);
break;
case 10:
mutator.SetQuery(acdata);
break;
case 11: {
const uint8_t index = get_numeric<uint8_t>(&buf, &size) %
(
sizeof(charsets) /
sizeof(
char*));
const char* charset = charsets[index];
auto encoding = mozilla::Encoding::ForLabelNoReplacement(
mozilla::MakeStringSpan(charset));
mutator.SetQueryWithEncoding(acdata, encoding);
break;
}
}
nsresult rv = mutator.Finalize(uri);
if (NS_FAILED(rv)) {
return 0;
}
}
else {
nsAutoCString out;
if (uri) {
switch (get_numeric<uint8_t>(&buf, &size) % 26) {
default:
uri->GetSpec(out);
break;
case 1:
uri->GetPrePath(out);
break;
case 2:
uri->GetScheme(out);
break;
case 3:
uri->GetUserPass(out);
break;
case 4:
uri->GetUsername(out);
break;
case 5:
uri->GetPassword(out);
break;
case 6:
uri->GetHostPort(out);
break;
case 7:
uri->GetHost(out);
break;
case 8: {
int rv;
uri->GetPort(&rv);
break;
}
case 9:
uri->GetPathQueryRef(out);
break;
case 10: {
nsCOMPtr<nsIURI> other;
bool rv;
nsAutoCString spec = get_string(&buf, &size);
NS_NewURI(getter_AddRefs(other), spec);
uri->Equals(other, &rv);
break;
}
case 11: {
nsAutoCString scheme = get_string(&buf, &size);
bool rv;
uri->SchemeIs(
"https", &rv);
break;
}
case 12: {
nsAutoCString in = get_string(&buf, &size);
uri->Resolve(in, out);
break;
}
case 13:
uri->GetAsciiSpec(out);
break;
case 14:
uri->GetAsciiHostPort(out);
break;
case 15:
uri->GetAsciiHost(out);
break;
case 16:
uri->GetRef(out);
break;
case 17: {
nsCOMPtr<nsIURI> other;
bool rv;
nsAutoCString spec = get_string(&buf, &size);
NS_NewURI(getter_AddRefs(other), spec);
uri->EqualsExceptRef(other, &rv);
break;
}
case 18:
uri->GetSpecIgnoringRef(out);
break;
case 19: {
bool rv;
uri->GetHasRef(&rv);
break;
}
case 20:
uri->GetFilePath(out);
break;
case 21:
uri->GetQuery(out);
break;
case 22:
uri->GetDisplayHost(out);
break;
case 23:
uri->GetDisplayHostPort(out);
break;
case 24:
uri->GetDisplaySpec(out);
break;
case 25:
uri->GetDisplayPrePath(out);
break;
}
}
}
}
return 0;
}
MOZ_FUZZING_INTERFACE_RAW(nullptr, FuzzingRunURIParser, URIParser);