Hash :
c6c6d8af
Author :
Date :
2024-12-11T16:24:23
fuzz: Mutate fuzz data chunks separately Implement a custom mutator that takes a list of fixed-size chunks which are mutated with a given probability. This makes sure that values like parser options or failure position are mutated regularly even as the fuzz data grows large. Values can also be adjusted temporarily to make the fuzzer focus on failure injection, for example. Thanks to David Kilzer for the idea.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116
/*
* uri.c: a libFuzzer target to test the URI module.
*
* See Copyright for the status of this software.
*/
#include <libxml/uri.h>
#include "fuzz.h"
int
LLVMFuzzerInitialize(int *argc ATTRIBUTE_UNUSED,
char ***argv ATTRIBUTE_UNUSED) {
xmlFuzzMemSetup();
return 0;
}
int
LLVMFuzzerTestOneInput(const char *data, size_t size) {
xmlURIPtr uri;
size_t failurePos;
const char *str1, *str2;
char *copy;
xmlChar *strRes;
int intRes;
if (size > 10000)
return(0);
xmlFuzzDataInit(data, size);
failurePos = xmlFuzzReadInt(4) % (size * 8 + 100);
str1 = xmlFuzzReadString(NULL);
str2 = xmlFuzzReadString(NULL);
xmlFuzzInjectFailure(failurePos);
xmlFuzzResetFailure();
intRes = xmlParseURISafe(str1, &uri);
xmlFuzzCheckFailureReport("xmlParseURISafe", intRes == -1, 0);
if (uri != NULL) {
xmlFuzzResetFailure();
strRes = xmlSaveUri(uri);
xmlFuzzCheckFailureReport("xmlSaveURI", strRes == NULL, 0);
xmlFree(strRes);
xmlFreeURI(uri);
}
xmlFreeURI(xmlParseURI(str1));
uri = xmlParseURIRaw(str1, 1);
xmlFree(xmlSaveUri(uri));
xmlFreeURI(uri);
xmlFuzzResetFailure();
strRes = BAD_CAST xmlURIUnescapeString(str1, -1, NULL);
xmlFuzzCheckFailureReport("xmlURIUnescapeString",
str1 != NULL && strRes == NULL, 0);
xmlFree(strRes);
xmlFree(xmlURIEscape(BAD_CAST str1));
xmlFuzzResetFailure();
strRes = xmlCanonicPath(BAD_CAST str1);
xmlFuzzCheckFailureReport("xmlCanonicPath",
str1 != NULL && strRes == NULL, 0);
xmlFree(strRes);
xmlFuzzResetFailure();
strRes = xmlPathToURI(BAD_CAST str1);
xmlFuzzCheckFailureReport("xmlPathToURI",
str1 != NULL && strRes == NULL, 0);
xmlFree(strRes);
xmlFuzzResetFailure();
intRes = xmlBuildURISafe(BAD_CAST str2, BAD_CAST str1, &strRes);
xmlFuzzCheckFailureReport("xmlBuildURISafe", intRes == -1, 0);
xmlFree(strRes);
xmlFree(xmlBuildURI(BAD_CAST str2, BAD_CAST str1));
xmlFuzzResetFailure();
intRes = xmlBuildRelativeURISafe(BAD_CAST str2, BAD_CAST str1, &strRes);
xmlFuzzCheckFailureReport("xmlBuildRelativeURISafe", intRes == -1, 0);
xmlFree(strRes);
xmlFree(xmlBuildRelativeURI(BAD_CAST str2, BAD_CAST str1));
xmlFuzzResetFailure();
strRes = xmlURIEscapeStr(BAD_CAST str1, BAD_CAST str2);
xmlFuzzCheckFailureReport("xmlURIEscapeStr",
str1 != NULL && strRes == NULL, 0);
xmlFree(strRes);
copy = (char *) xmlCharStrdup(str1);
xmlNormalizeURIPath(copy);
xmlFree(copy);
xmlFuzzInjectFailure(0);
xmlFuzzDataCleanup();
return 0;
}
size_t
LLVMFuzzerCustomMutator(char *data, size_t size, size_t maxSize,
unsigned seed) {
static const xmlFuzzChunkDesc chunks[] = {
{ 4, XML_FUZZ_PROB_ONE / 10 }, /* failurePos */
{ 0, 0 }
};
return xmlFuzzMutateChunks(chunks, data, size, maxSize, seed,
LLVMFuzzerMutate);
}