1 /*
2 * testFuzzer.c: Test program for the custom entity loader used to fuzz
3 * with multiple inputs.
4 *
5 * See Copyright for the status of this software.
6 */
7
8 #include <string.h>
9 #include <glob.h>
10 #include <libxml/parser.h>
11 #include <libxml/tree.h>
12 #include <libxml/xmlstring.h>
13 #include "fuzz.h"
14
15 #ifdef HAVE_HTML_FUZZER
16 #define LLVMFuzzerInitialize fuzzHtmlInit
17 #define LLVMFuzzerTestOneInput fuzzHtml
18 #include "html.c"
19 #undef LLVMFuzzerInitialize
20 #undef LLVMFuzzerTestOneInput
21 #endif
22
23 #ifdef HAVE_REGEXP_FUZZER
24 #define LLVMFuzzerInitialize fuzzRegexpInit
25 #define LLVMFuzzerTestOneInput fuzzRegexp
26 #include "regexp.c"
27 #undef LLVMFuzzerInitialize
28 #undef LLVMFuzzerTestOneInput
29 #endif
30
31 #ifdef HAVE_SCHEMA_FUZZER
32 #define LLVMFuzzerInitialize fuzzSchemaInit
33 #define LLVMFuzzerTestOneInput fuzzSchema
34 #include "schema.c"
35 #undef LLVMFuzzerInitialize
36 #undef LLVMFuzzerTestOneInput
37 #endif
38
39 #ifdef HAVE_URI_FUZZER
40 #define LLVMFuzzerInitialize fuzzUriInit
41 #define LLVMFuzzerTestOneInput fuzzUri
42 #include "uri.c"
43 #undef LLVMFuzzerInitialize
44 #undef LLVMFuzzerTestOneInput
45 #endif
46
47 #ifdef HAVE_XML_FUZZER
48 #define LLVMFuzzerInitialize fuzzXmlInit
49 #define LLVMFuzzerTestOneInput fuzzXml
50 #include "xml.c"
51 #undef LLVMFuzzerInitialize
52 #undef LLVMFuzzerTestOneInput
53 #endif
54
55 #ifdef HAVE_XPATH_FUZZER
56 #define LLVMFuzzerInitialize fuzzXPathInit
57 #define LLVMFuzzerTestOneInput fuzzXPath
58 #include "xpath.c"
59 #undef LLVMFuzzerInitialize
60 #undef LLVMFuzzerTestOneInput
61 #endif
62
63 typedef int
64 (*initFunc)(int *argc, char ***argv);
65 typedef int
66 (*fuzzFunc)(const char *data, size_t size);
67
68 int numInputs;
69
70 static int
testFuzzer(initFunc init,fuzzFunc fuzz,const char * pattern)71 testFuzzer(initFunc init, fuzzFunc fuzz, const char *pattern) {
72 glob_t globbuf;
73 int ret = -1;
74 int i;
75
76 if (glob(pattern, 0, NULL, &globbuf) != 0) {
77 fprintf(stderr, "pattern %s matches no files\n", pattern);
78 return(-1);
79 }
80
81 if (init != NULL)
82 init(NULL, NULL);
83
84 for (i = 0; i < globbuf.gl_pathc; i++) {
85 const char *path = globbuf.gl_pathv[i];
86 char *data;
87 size_t size;
88
89 data = xmlSlurpFile(path, &size);
90 if (data == NULL) {
91 fprintf(stderr, "couldn't read %s\n", path);
92 goto error;
93 }
94 fuzz(data, size);
95 xmlFree(data);
96
97 numInputs++;
98 }
99
100 ret = 0;
101 error:
102 globfree(&globbuf);
103 return(ret);
104 }
105
106 #ifdef HAVE_XML_FUZZER
107 static int
testEntityLoader()108 testEntityLoader() {
109 static const char data[] =
110 "doc.xml\\\n"
111 "<!DOCTYPE doc SYSTEM \"doc.dtd\">\n"
112 "<doc>&ent;</doc>\\\n"
113 "doc.dtd\\\n"
114 "<!ELEMENT doc (#PCDATA)>\n"
115 "<!ENTITY ent SYSTEM \"ent.txt\">\\\n"
116 "ent.txt\\\n"
117 "Hello, world!\\\n";
118 static xmlChar expected[] =
119 "<?xml version=\"1.0\"?>\n"
120 "<!DOCTYPE doc SYSTEM \"doc.dtd\">\n"
121 "<doc>Hello, world!</doc>\n";
122 const char *docBuffer;
123 size_t docSize;
124 xmlDocPtr doc;
125 xmlChar *out;
126 int ret = 0;
127
128 xmlSetExternalEntityLoader(xmlFuzzEntityLoader);
129
130 xmlFuzzDataInit(data, sizeof(data) - 1);
131 xmlFuzzReadEntities();
132 docBuffer = xmlFuzzMainEntity(&docSize);
133 doc = xmlReadMemory(docBuffer, docSize, NULL, NULL,
134 XML_PARSE_NOENT | XML_PARSE_DTDLOAD);
135
136 xmlDocDumpMemory(doc, &out, NULL);
137 if (xmlStrcmp(out, expected) != 0) {
138 fprintf(stderr, "Expected:\n%sGot:\n%s", expected, out);
139 ret = 1;
140 }
141
142 xmlFree(out);
143 xmlFreeDoc(doc);
144 xmlFuzzDataCleanup();
145
146 return(ret);
147 }
148 #endif
149
150 int
main()151 main() {
152 int ret = 0;
153
154 #ifdef HAVE_XML_FUZZER
155 if (testEntityLoader() != 0)
156 ret = 1;
157 #endif
158 #ifdef HAVE_HTML_FUZZER
159 if (testFuzzer(fuzzHtmlInit, fuzzHtml, "seed/html/*") != 0)
160 ret = 1;
161 #endif
162 #ifdef HAVE_REGEXP_FUZZER
163 if (testFuzzer(fuzzRegexpInit, fuzzRegexp, "seed/regexp/*") != 0)
164 ret = 1;
165 #endif
166 #ifdef HAVE_SCHEMA_FUZZER
167 if (testFuzzer(fuzzSchemaInit, fuzzSchema, "seed/schema/*") != 0)
168 ret = 1;
169 #endif
170 #ifdef HAVE_URI_FUZZER
171 if (testFuzzer(NULL, fuzzUri, "seed/uri/*") != 0)
172 ret = 1;
173 #endif
174 #ifdef HAVE_XML_FUZZER
175 if (testFuzzer(fuzzXmlInit, fuzzXml, "seed/xml/*") != 0)
176 ret = 1;
177 #endif
178 #ifdef HAVE_XPATH_FUZZER
179 if (testFuzzer(fuzzXPathInit, fuzzXPath, "seed/xpath/*") != 0)
180 ret = 1;
181 #endif
182
183 if (ret == 0)
184 printf("Successfully tested %d inputs\n", numInputs);
185
186 return(ret);
187 }
188
189