TestURIFuzzing.cpp (6500B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 6 7 #include <iostream> 8 9 #include "FuzzingInterface.h" 10 #include "nsComponentManagerUtils.h" 11 #include "nsCOMPtr.h" 12 #include "nsIURL.h" 13 #include "nsIStandardURL.h" 14 #include "nsIURIMutator.h" 15 #include "nsNetUtil.h" 16 #include "nsNetCID.h" 17 #include "nsPrintfCString.h" 18 #include "nsString.h" 19 #include "mozilla/Encoding.h" 20 #include "mozilla/Span.h" 21 22 template <typename T> 23 T get_numeric(char** buf, size_t* size) { 24 if (sizeof(T) > *size) { 25 return 0; 26 } 27 28 T* iptr = reinterpret_cast<T*>(*buf); 29 *buf += sizeof(T); 30 *size -= sizeof(T); 31 return *iptr; 32 } 33 34 nsAutoCString get_string(char** buf, size_t* size) { 35 uint8_t len = get_numeric<uint8_t>(buf, size); 36 if (len > *size) { 37 len = static_cast<uint8_t>(*size); 38 } 39 nsAutoCString str(*buf, len); 40 41 *buf += len; 42 *size -= len; 43 return str; 44 } 45 46 const char* charsets[] = { 47 "Big5", "EUC-JP", "EUC-KR", "gb18030", 48 "gbk", "IBM866", "ISO-2022-JP", "ISO-8859-10", 49 "ISO-8859-13", "ISO-8859-14", "ISO-8859-15", "ISO-8859-16", 50 "ISO-8859-2", "ISO-8859-3", "ISO-8859-4", "ISO-8859-5", 51 "ISO-8859-6", "ISO-8859-7", "ISO-8859-8", "ISO-8859-8-I", 52 "KOI8-R", "KOI8-U", "macintosh", "replacement", 53 "Shift_JIS", "UTF-16BE", "UTF-16LE", "UTF-8", 54 "windows-1250", "windows-1251", "windows-1252", "windows-1253", 55 "windows-1254", "windows-1255", "windows-1256", "windows-1257", 56 "windows-1258", "windows-874", "x-mac-cyrillic", "x-user-defined"}; 57 58 static int FuzzingRunURIParser(const uint8_t* data, size_t size) { 59 char* buf = (char*)data; 60 61 nsCOMPtr<nsIURI> uri; 62 nsAutoCString spec = get_string(&buf, &size); 63 64 nsresult rv = NS_NewURI(getter_AddRefs(uri), spec); 65 66 if (NS_FAILED(rv)) { 67 return 0; 68 } 69 70 uint8_t iters = get_numeric<uint8_t>(&buf, &size); 71 for (int i = 0; i < iters; i++) { 72 if (get_numeric<uint8_t>(&buf, &size) % 25 != 0) { 73 NS_MutateURI mutator(uri); 74 nsAutoCString acdata = get_string(&buf, &size); 75 76 switch (get_numeric<uint8_t>(&buf, &size) % 12) { 77 default: 78 mutator.SetSpec(acdata); 79 break; 80 case 1: 81 mutator.SetScheme(acdata); 82 break; 83 case 2: 84 mutator.SetUserPass(acdata); 85 break; 86 case 3: 87 mutator.SetUsername(acdata); 88 break; 89 case 4: 90 mutator.SetPassword(acdata); 91 break; 92 case 5: 93 mutator.SetHostPort(acdata); 94 break; 95 case 6: 96 // Called via SetHostPort 97 mutator.SetHost(acdata); 98 break; 99 case 7: 100 // Called via multiple paths 101 mutator.SetPathQueryRef(acdata); 102 break; 103 case 8: 104 mutator.SetRef(acdata); 105 break; 106 case 9: 107 mutator.SetFilePath(acdata); 108 break; 109 case 10: 110 mutator.SetQuery(acdata); 111 break; 112 case 11: { 113 const uint8_t index = get_numeric<uint8_t>(&buf, &size) % 114 (sizeof(charsets) / sizeof(char*)); 115 const char* charset = charsets[index]; 116 auto encoding = mozilla::Encoding::ForLabelNoReplacement( 117 mozilla::MakeStringSpan(charset)); 118 mutator.SetQueryWithEncoding(acdata, encoding); 119 break; 120 } 121 } 122 123 nsresult rv = mutator.Finalize(uri); 124 if (NS_FAILED(rv)) { 125 return 0; 126 } 127 } else { 128 nsAutoCString out; 129 130 if (uri) { 131 switch (get_numeric<uint8_t>(&buf, &size) % 26) { 132 default: 133 uri->GetSpec(out); 134 break; 135 case 1: 136 uri->GetPrePath(out); 137 break; 138 case 2: 139 uri->GetScheme(out); 140 break; 141 case 3: 142 uri->GetUserPass(out); 143 break; 144 case 4: 145 uri->GetUsername(out); 146 break; 147 case 5: 148 uri->GetPassword(out); 149 break; 150 case 6: 151 uri->GetHostPort(out); 152 break; 153 case 7: 154 uri->GetHost(out); 155 break; 156 case 8: { 157 int rv; 158 uri->GetPort(&rv); 159 break; 160 } 161 case 9: 162 uri->GetPathQueryRef(out); 163 break; 164 case 10: { 165 nsCOMPtr<nsIURI> other; 166 bool rv; 167 nsAutoCString spec = get_string(&buf, &size); 168 NS_NewURI(getter_AddRefs(other), spec); 169 uri->Equals(other, &rv); 170 break; 171 } 172 case 11: { 173 nsAutoCString scheme = get_string(&buf, &size); 174 bool rv; 175 uri->SchemeIs("https", &rv); 176 break; 177 } 178 case 12: { 179 nsAutoCString in = get_string(&buf, &size); 180 uri->Resolve(in, out); 181 break; 182 } 183 case 13: 184 uri->GetAsciiSpec(out); 185 break; 186 case 14: 187 uri->GetAsciiHostPort(out); 188 break; 189 case 15: 190 uri->GetAsciiHost(out); 191 break; 192 case 16: 193 uri->GetRef(out); 194 break; 195 case 17: { 196 nsCOMPtr<nsIURI> other; 197 bool rv; 198 nsAutoCString spec = get_string(&buf, &size); 199 NS_NewURI(getter_AddRefs(other), spec); 200 uri->EqualsExceptRef(other, &rv); 201 break; 202 } 203 case 18: 204 uri->GetSpecIgnoringRef(out); 205 break; 206 case 19: { 207 bool rv; 208 uri->GetHasRef(&rv); 209 break; 210 } 211 case 20: 212 uri->GetFilePath(out); 213 break; 214 case 21: 215 uri->GetQuery(out); 216 break; 217 case 22: 218 uri->GetDisplayHost(out); 219 break; 220 case 23: 221 uri->GetDisplayHostPort(out); 222 break; 223 case 24: 224 uri->GetDisplaySpec(out); 225 break; 226 case 25: 227 uri->GetDisplayPrePath(out); 228 break; 229 } 230 } 231 } 232 } 233 234 return 0; 235 } 236 237 MOZ_FUZZING_INTERFACE_RAW(nullptr, FuzzingRunURIParser, URIParser);