зеркало из https://github.com/mozilla/gecko-dev.git
236 строки
6.4 KiB
C++
236 строки
6.4 KiB
C++
/* -*- 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_MutateURI(NS_STANDARDURLMUTATOR_CONTRACTID)
|
|
.SetSpec(spec)
|
|
.Finalize(uri);
|
|
|
|
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;
|
|
}
|
|
}
|
|
} 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);
|