/* * testFuzzer.c: Test program for the custom entity loader used to fuzz * with multiple inputs. * * See Copyright for the status of this software. */ #include #include #include #include #include #include "fuzz.h" #ifdef HAVE_HTML_FUZZER int fuzzHtmlInit(int *argc, char ***argv); int fuzzHtml(const char *data, size_t size); #define LLVMFuzzerInitialize fuzzHtmlInit #define LLVMFuzzerTestOneInput fuzzHtml #include "html.c" #undef LLVMFuzzerInitialize #undef LLVMFuzzerTestOneInput #endif #ifdef HAVE_REGEXP_FUZZER int fuzzRegexpInit(int *argc, char ***argv); int fuzzRegexp(const char *data, size_t size); #define LLVMFuzzerInitialize fuzzRegexpInit #define LLVMFuzzerTestOneInput fuzzRegexp #include "regexp.c" #undef LLVMFuzzerInitialize #undef LLVMFuzzerTestOneInput #endif #ifdef HAVE_SCHEMA_FUZZER int fuzzSchemaInit(int *argc, char ***argv); int fuzzSchema(const char *data, size_t size); #define LLVMFuzzerInitialize fuzzSchemaInit #define LLVMFuzzerTestOneInput fuzzSchema #include "schema.c" #undef LLVMFuzzerInitialize #undef LLVMFuzzerTestOneInput #endif #ifdef HAVE_URI_FUZZER int fuzzUriInit(int *argc, char ***argv); int fuzzUri(const char *data, size_t size); #define LLVMFuzzerInitialize fuzzUriInit #define LLVMFuzzerTestOneInput fuzzUri #include "uri.c" #undef LLVMFuzzerInitialize #undef LLVMFuzzerTestOneInput #endif #ifdef HAVE_VALID_FUZZER int fuzzValidInit(int *argc, char ***argv); int fuzzValid(const char *data, size_t size); #define LLVMFuzzerInitialize fuzzValidInit #define LLVMFuzzerTestOneInput fuzzValid #include "valid.c" #undef LLVMFuzzerInitialize #undef LLVMFuzzerTestOneInput #endif #ifdef HAVE_XINCLUDE_FUZZER int fuzzXIncludeInit(int *argc, char ***argv); int fuzzXInclude(const char *data, size_t size); #define LLVMFuzzerInitialize fuzzXIncludeInit #define LLVMFuzzerTestOneInput fuzzXInclude #include "xinclude.c" #undef LLVMFuzzerInitialize #undef LLVMFuzzerTestOneInput #endif #ifdef HAVE_XML_FUZZER int fuzzXmlInit(int *argc, char ***argv); int fuzzXml(const char *data, size_t size); #define LLVMFuzzerInitialize fuzzXmlInit #define LLVMFuzzerTestOneInput fuzzXml #include "xml.c" #undef LLVMFuzzerInitialize #undef LLVMFuzzerTestOneInput #endif #ifdef HAVE_XPATH_FUZZER int fuzzXPathInit(int *argc, char ***argv); int fuzzXPath(const char *data, size_t size); #define LLVMFuzzerInitialize fuzzXPathInit #define LLVMFuzzerTestOneInput fuzzXPath #include "xpath.c" #undef LLVMFuzzerInitialize #undef LLVMFuzzerTestOneInput #endif typedef int (*initFunc)(int *argc, char ***argv); typedef int (*fuzzFunc)(const char *data, size_t size); int numInputs; static int testFuzzer(initFunc init, fuzzFunc fuzz, const char *pattern) { glob_t globbuf; int ret = -1; size_t i; if (glob(pattern, 0, NULL, &globbuf) != 0) { fprintf(stderr, "pattern %s matches no files\n", pattern); return(-1); } if (init != NULL) init(NULL, NULL); for (i = 0; i < globbuf.gl_pathc; i++) { const char *path = globbuf.gl_pathv[i]; char *data; size_t size; data = xmlSlurpFile(path, &size); if (data == NULL) { fprintf(stderr, "couldn't read %s\n", path); goto error; } fuzz(data, size); xmlFree(data); numInputs++; } ret = 0; error: globfree(&globbuf); return(ret); } #ifdef HAVE_XML_FUZZER static int testEntityLoader(void) { static const char data[] = "doc.xml\\\n" "\n" "&ent;\\\n" "doc.dtd\\\n" "\n" "\\\n" "ent.txt\\\n" "Hello, world!\\\n"; static xmlChar expected[] = "\n" "\n" "Hello, world!\n"; const char *docBuffer; size_t docSize; xmlDocPtr doc; xmlChar *out; int ret = 0; xmlSetExternalEntityLoader(xmlFuzzEntityLoader); xmlFuzzDataInit(data, sizeof(data) - 1); xmlFuzzReadEntities(); docBuffer = xmlFuzzMainEntity(&docSize); doc = xmlReadMemory(docBuffer, docSize, NULL, NULL, XML_PARSE_NOENT | XML_PARSE_DTDLOAD); xmlDocDumpMemory(doc, &out, NULL); if (xmlStrcmp(out, expected) != 0) { fprintf(stderr, "Expected:\n%sGot:\n%s", expected, out); ret = 1; } xmlFree(out); xmlFreeDoc(doc); xmlFuzzDataCleanup(); return(ret); } #endif int main(void) { int ret = 0; #ifdef HAVE_XML_FUZZER if (testEntityLoader() != 0) ret = 1; #endif #ifdef HAVE_HTML_FUZZER if (testFuzzer(fuzzHtmlInit, fuzzHtml, "seed/html/*") != 0) ret = 1; #endif #ifdef HAVE_REGEXP_FUZZER if (testFuzzer(fuzzRegexpInit, fuzzRegexp, "seed/regexp/*") != 0) ret = 1; #endif #ifdef HAVE_SCHEMA_FUZZER if (testFuzzer(fuzzSchemaInit, fuzzSchema, "seed/schema/*") != 0) ret = 1; #endif #ifdef HAVE_URI_FUZZER if (testFuzzer(fuzzUriInit, fuzzUri, "seed/uri/*") != 0) ret = 1; #endif #ifdef HAVE_VALID_FUZZER if (testFuzzer(fuzzValidInit, fuzzValid, "seed/valid/*") != 0) ret = 1; #endif #ifdef HAVE_XINCLUDE_FUZZER if (testFuzzer(fuzzXIncludeInit, fuzzXInclude, "seed/xinclude/*") != 0) ret = 1; #endif #ifdef HAVE_XML_FUZZER if (testFuzzer(fuzzXmlInit, fuzzXml, "seed/xml/*") != 0) ret = 1; #endif #ifdef HAVE_XPATH_FUZZER if (testFuzzer(fuzzXPathInit, fuzzXPath, "seed/xpath/*") != 0) ret = 1; #endif if (ret == 0) printf("Successfully tested %d inputs\n", numInputs); return(ret); }