xref: /aosp_15_r20/external/libxml2/fuzz/testFuzzer.c (revision 7c5688314b92172186c154356a6374bf7684c3ca)
1*7c568831SAndroid Build Coastguard Worker /*
2*7c568831SAndroid Build Coastguard Worker  * testFuzzer.c: Test program for the custom entity loader used to fuzz
3*7c568831SAndroid Build Coastguard Worker  * with multiple inputs.
4*7c568831SAndroid Build Coastguard Worker  *
5*7c568831SAndroid Build Coastguard Worker  * See Copyright for the status of this software.
6*7c568831SAndroid Build Coastguard Worker  */
7*7c568831SAndroid Build Coastguard Worker 
8*7c568831SAndroid Build Coastguard Worker #include <string.h>
9*7c568831SAndroid Build Coastguard Worker #include <glob.h>
10*7c568831SAndroid Build Coastguard Worker #include <libxml/parser.h>
11*7c568831SAndroid Build Coastguard Worker #include <libxml/tree.h>
12*7c568831SAndroid Build Coastguard Worker #include <libxml/xmlstring.h>
13*7c568831SAndroid Build Coastguard Worker #include "fuzz.h"
14*7c568831SAndroid Build Coastguard Worker 
15*7c568831SAndroid Build Coastguard Worker #ifdef HAVE_HTML_FUZZER
16*7c568831SAndroid Build Coastguard Worker int fuzzHtmlInit(int *argc, char ***argv);
17*7c568831SAndroid Build Coastguard Worker int fuzzHtml(const char *data, size_t size);
18*7c568831SAndroid Build Coastguard Worker #define LLVMFuzzerInitialize fuzzHtmlInit
19*7c568831SAndroid Build Coastguard Worker #define LLVMFuzzerTestOneInput fuzzHtml
20*7c568831SAndroid Build Coastguard Worker #include "html.c"
21*7c568831SAndroid Build Coastguard Worker #undef LLVMFuzzerInitialize
22*7c568831SAndroid Build Coastguard Worker #undef LLVMFuzzerTestOneInput
23*7c568831SAndroid Build Coastguard Worker #endif
24*7c568831SAndroid Build Coastguard Worker 
25*7c568831SAndroid Build Coastguard Worker #ifdef HAVE_READER_FUZZER
26*7c568831SAndroid Build Coastguard Worker int fuzzReaderInit(int *argc, char ***argv);
27*7c568831SAndroid Build Coastguard Worker int fuzzReader(const char *data, size_t size);
28*7c568831SAndroid Build Coastguard Worker #define LLVMFuzzerInitialize fuzzReaderInit
29*7c568831SAndroid Build Coastguard Worker #define LLVMFuzzerTestOneInput fuzzReader
30*7c568831SAndroid Build Coastguard Worker #include "reader.c"
31*7c568831SAndroid Build Coastguard Worker #undef LLVMFuzzerInitialize
32*7c568831SAndroid Build Coastguard Worker #undef LLVMFuzzerTestOneInput
33*7c568831SAndroid Build Coastguard Worker #endif
34*7c568831SAndroid Build Coastguard Worker 
35*7c568831SAndroid Build Coastguard Worker #ifdef HAVE_REGEXP_FUZZER
36*7c568831SAndroid Build Coastguard Worker int fuzzRegexpInit(int *argc, char ***argv);
37*7c568831SAndroid Build Coastguard Worker int fuzzRegexp(const char *data, size_t size);
38*7c568831SAndroid Build Coastguard Worker #define LLVMFuzzerInitialize fuzzRegexpInit
39*7c568831SAndroid Build Coastguard Worker #define LLVMFuzzerTestOneInput fuzzRegexp
40*7c568831SAndroid Build Coastguard Worker #include "regexp.c"
41*7c568831SAndroid Build Coastguard Worker #undef LLVMFuzzerInitialize
42*7c568831SAndroid Build Coastguard Worker #undef LLVMFuzzerTestOneInput
43*7c568831SAndroid Build Coastguard Worker #endif
44*7c568831SAndroid Build Coastguard Worker 
45*7c568831SAndroid Build Coastguard Worker #ifdef HAVE_SCHEMA_FUZZER
46*7c568831SAndroid Build Coastguard Worker int fuzzSchemaInit(int *argc, char ***argv);
47*7c568831SAndroid Build Coastguard Worker int fuzzSchema(const char *data, size_t size);
48*7c568831SAndroid Build Coastguard Worker #define LLVMFuzzerInitialize fuzzSchemaInit
49*7c568831SAndroid Build Coastguard Worker #define LLVMFuzzerTestOneInput fuzzSchema
50*7c568831SAndroid Build Coastguard Worker #include "schema.c"
51*7c568831SAndroid Build Coastguard Worker #undef LLVMFuzzerInitialize
52*7c568831SAndroid Build Coastguard Worker #undef LLVMFuzzerTestOneInput
53*7c568831SAndroid Build Coastguard Worker #endif
54*7c568831SAndroid Build Coastguard Worker 
55*7c568831SAndroid Build Coastguard Worker #ifdef HAVE_URI_FUZZER
56*7c568831SAndroid Build Coastguard Worker int fuzzUriInit(int *argc, char ***argv);
57*7c568831SAndroid Build Coastguard Worker int fuzzUri(const char *data, size_t size);
58*7c568831SAndroid Build Coastguard Worker #define LLVMFuzzerInitialize fuzzUriInit
59*7c568831SAndroid Build Coastguard Worker #define LLVMFuzzerTestOneInput fuzzUri
60*7c568831SAndroid Build Coastguard Worker #include "uri.c"
61*7c568831SAndroid Build Coastguard Worker #undef LLVMFuzzerInitialize
62*7c568831SAndroid Build Coastguard Worker #undef LLVMFuzzerTestOneInput
63*7c568831SAndroid Build Coastguard Worker #endif
64*7c568831SAndroid Build Coastguard Worker 
65*7c568831SAndroid Build Coastguard Worker #ifdef HAVE_VALID_FUZZER
66*7c568831SAndroid Build Coastguard Worker int fuzzValidInit(int *argc, char ***argv);
67*7c568831SAndroid Build Coastguard Worker int fuzzValid(const char *data, size_t size);
68*7c568831SAndroid Build Coastguard Worker #define LLVMFuzzerInitialize fuzzValidInit
69*7c568831SAndroid Build Coastguard Worker #define LLVMFuzzerTestOneInput fuzzValid
70*7c568831SAndroid Build Coastguard Worker #include "valid.c"
71*7c568831SAndroid Build Coastguard Worker #undef LLVMFuzzerInitialize
72*7c568831SAndroid Build Coastguard Worker #undef LLVMFuzzerTestOneInput
73*7c568831SAndroid Build Coastguard Worker #endif
74*7c568831SAndroid Build Coastguard Worker 
75*7c568831SAndroid Build Coastguard Worker #ifdef HAVE_XINCLUDE_FUZZER
76*7c568831SAndroid Build Coastguard Worker int fuzzXIncludeInit(int *argc, char ***argv);
77*7c568831SAndroid Build Coastguard Worker int fuzzXInclude(const char *data, size_t size);
78*7c568831SAndroid Build Coastguard Worker #define LLVMFuzzerInitialize fuzzXIncludeInit
79*7c568831SAndroid Build Coastguard Worker #define LLVMFuzzerTestOneInput fuzzXInclude
80*7c568831SAndroid Build Coastguard Worker #include "xinclude.c"
81*7c568831SAndroid Build Coastguard Worker #undef LLVMFuzzerInitialize
82*7c568831SAndroid Build Coastguard Worker #undef LLVMFuzzerTestOneInput
83*7c568831SAndroid Build Coastguard Worker #endif
84*7c568831SAndroid Build Coastguard Worker 
85*7c568831SAndroid Build Coastguard Worker #ifdef HAVE_XML_FUZZER
86*7c568831SAndroid Build Coastguard Worker int fuzzXmlInit(int *argc, char ***argv);
87*7c568831SAndroid Build Coastguard Worker int fuzzXml(const char *data, size_t size);
88*7c568831SAndroid Build Coastguard Worker #define LLVMFuzzerInitialize fuzzXmlInit
89*7c568831SAndroid Build Coastguard Worker #define LLVMFuzzerTestOneInput fuzzXml
90*7c568831SAndroid Build Coastguard Worker #include "xml.c"
91*7c568831SAndroid Build Coastguard Worker #undef LLVMFuzzerInitialize
92*7c568831SAndroid Build Coastguard Worker #undef LLVMFuzzerTestOneInput
93*7c568831SAndroid Build Coastguard Worker #endif
94*7c568831SAndroid Build Coastguard Worker 
95*7c568831SAndroid Build Coastguard Worker #ifdef HAVE_XPATH_FUZZER
96*7c568831SAndroid Build Coastguard Worker int fuzzXPathInit(int *argc, char ***argv);
97*7c568831SAndroid Build Coastguard Worker int fuzzXPath(const char *data, size_t size);
98*7c568831SAndroid Build Coastguard Worker #define LLVMFuzzerInitialize fuzzXPathInit
99*7c568831SAndroid Build Coastguard Worker #define LLVMFuzzerTestOneInput fuzzXPath
100*7c568831SAndroid Build Coastguard Worker #include "xpath.c"
101*7c568831SAndroid Build Coastguard Worker #undef LLVMFuzzerInitialize
102*7c568831SAndroid Build Coastguard Worker #undef LLVMFuzzerTestOneInput
103*7c568831SAndroid Build Coastguard Worker #endif
104*7c568831SAndroid Build Coastguard Worker 
105*7c568831SAndroid Build Coastguard Worker typedef int
106*7c568831SAndroid Build Coastguard Worker (*initFunc)(int *argc, char ***argv);
107*7c568831SAndroid Build Coastguard Worker typedef int
108*7c568831SAndroid Build Coastguard Worker (*fuzzFunc)(const char *data, size_t size);
109*7c568831SAndroid Build Coastguard Worker 
110*7c568831SAndroid Build Coastguard Worker int numInputs;
111*7c568831SAndroid Build Coastguard Worker 
112*7c568831SAndroid Build Coastguard Worker static int
testFuzzer(initFunc init,fuzzFunc fuzz,const char * pattern)113*7c568831SAndroid Build Coastguard Worker testFuzzer(initFunc init, fuzzFunc fuzz, const char *pattern) {
114*7c568831SAndroid Build Coastguard Worker     glob_t globbuf;
115*7c568831SAndroid Build Coastguard Worker     int ret = -1;
116*7c568831SAndroid Build Coastguard Worker     size_t i;
117*7c568831SAndroid Build Coastguard Worker 
118*7c568831SAndroid Build Coastguard Worker     if (glob(pattern, 0, NULL, &globbuf) != 0) {
119*7c568831SAndroid Build Coastguard Worker         fprintf(stderr, "pattern %s matches no files\n", pattern);
120*7c568831SAndroid Build Coastguard Worker         return(-1);
121*7c568831SAndroid Build Coastguard Worker     }
122*7c568831SAndroid Build Coastguard Worker 
123*7c568831SAndroid Build Coastguard Worker     if (init != NULL)
124*7c568831SAndroid Build Coastguard Worker         init(NULL, NULL);
125*7c568831SAndroid Build Coastguard Worker 
126*7c568831SAndroid Build Coastguard Worker     for (i = 0; i < globbuf.gl_pathc; i++) {
127*7c568831SAndroid Build Coastguard Worker         const char *path = globbuf.gl_pathv[i];
128*7c568831SAndroid Build Coastguard Worker         char *data;
129*7c568831SAndroid Build Coastguard Worker         size_t size;
130*7c568831SAndroid Build Coastguard Worker 
131*7c568831SAndroid Build Coastguard Worker         data = xmlSlurpFile(path, &size);
132*7c568831SAndroid Build Coastguard Worker         if (data == NULL) {
133*7c568831SAndroid Build Coastguard Worker             fprintf(stderr, "couldn't read %s\n", path);
134*7c568831SAndroid Build Coastguard Worker             goto error;
135*7c568831SAndroid Build Coastguard Worker         }
136*7c568831SAndroid Build Coastguard Worker         fuzz(data, size);
137*7c568831SAndroid Build Coastguard Worker         xmlFree(data);
138*7c568831SAndroid Build Coastguard Worker 
139*7c568831SAndroid Build Coastguard Worker         numInputs++;
140*7c568831SAndroid Build Coastguard Worker     }
141*7c568831SAndroid Build Coastguard Worker 
142*7c568831SAndroid Build Coastguard Worker     ret = 0;
143*7c568831SAndroid Build Coastguard Worker error:
144*7c568831SAndroid Build Coastguard Worker     globfree(&globbuf);
145*7c568831SAndroid Build Coastguard Worker     return(ret);
146*7c568831SAndroid Build Coastguard Worker }
147*7c568831SAndroid Build Coastguard Worker 
148*7c568831SAndroid Build Coastguard Worker #ifdef HAVE_XML_FUZZER
149*7c568831SAndroid Build Coastguard Worker static int
testEntityLoader(void)150*7c568831SAndroid Build Coastguard Worker testEntityLoader(void) {
151*7c568831SAndroid Build Coastguard Worker     xmlParserCtxtPtr ctxt;
152*7c568831SAndroid Build Coastguard Worker     static const char data[] =
153*7c568831SAndroid Build Coastguard Worker         "doc.xml\\\n"
154*7c568831SAndroid Build Coastguard Worker         "<!DOCTYPE doc SYSTEM \"doc.dtd\">\n"
155*7c568831SAndroid Build Coastguard Worker         "<doc>&ent;</doc>\\\n"
156*7c568831SAndroid Build Coastguard Worker         "doc.dtd\\\n"
157*7c568831SAndroid Build Coastguard Worker         "<!ELEMENT doc (#PCDATA)>\n"
158*7c568831SAndroid Build Coastguard Worker         "<!ENTITY ent SYSTEM \"ent.txt\">\\\n"
159*7c568831SAndroid Build Coastguard Worker         "ent.txt\\\n"
160*7c568831SAndroid Build Coastguard Worker         "Hello, world!\\\n";
161*7c568831SAndroid Build Coastguard Worker     const char *docBuffer;
162*7c568831SAndroid Build Coastguard Worker     size_t docSize;
163*7c568831SAndroid Build Coastguard Worker     xmlDocPtr doc;
164*7c568831SAndroid Build Coastguard Worker     int ret = 0;
165*7c568831SAndroid Build Coastguard Worker 
166*7c568831SAndroid Build Coastguard Worker     xmlFuzzDataInit(data, sizeof(data) - 1);
167*7c568831SAndroid Build Coastguard Worker     xmlFuzzReadEntities();
168*7c568831SAndroid Build Coastguard Worker     docBuffer = xmlFuzzMainEntity(&docSize);
169*7c568831SAndroid Build Coastguard Worker     ctxt = xmlNewParserCtxt();
170*7c568831SAndroid Build Coastguard Worker     xmlCtxtSetResourceLoader(ctxt, xmlFuzzResourceLoader, NULL);
171*7c568831SAndroid Build Coastguard Worker     doc = xmlCtxtReadMemory(ctxt, docBuffer, docSize, NULL, NULL,
172*7c568831SAndroid Build Coastguard Worker                             XML_PARSE_NOENT | XML_PARSE_DTDLOAD);
173*7c568831SAndroid Build Coastguard Worker     xmlFreeParserCtxt(ctxt);
174*7c568831SAndroid Build Coastguard Worker 
175*7c568831SAndroid Build Coastguard Worker #ifdef LIBXML_OUTPUT_ENABLED
176*7c568831SAndroid Build Coastguard Worker     {
177*7c568831SAndroid Build Coastguard Worker         static xmlChar expected[] =
178*7c568831SAndroid Build Coastguard Worker             "<?xml version=\"1.0\"?>\n"
179*7c568831SAndroid Build Coastguard Worker             "<!DOCTYPE doc SYSTEM \"doc.dtd\">\n"
180*7c568831SAndroid Build Coastguard Worker             "<doc>Hello, world!</doc>\n";
181*7c568831SAndroid Build Coastguard Worker         xmlChar *out;
182*7c568831SAndroid Build Coastguard Worker 
183*7c568831SAndroid Build Coastguard Worker         xmlDocDumpMemory(doc, &out, NULL);
184*7c568831SAndroid Build Coastguard Worker         if (xmlStrcmp(out, expected) != 0) {
185*7c568831SAndroid Build Coastguard Worker             fprintf(stderr, "Expected:\n%sGot:\n%s", expected, out);
186*7c568831SAndroid Build Coastguard Worker             ret = 1;
187*7c568831SAndroid Build Coastguard Worker         }
188*7c568831SAndroid Build Coastguard Worker         xmlFree(out);
189*7c568831SAndroid Build Coastguard Worker     }
190*7c568831SAndroid Build Coastguard Worker #endif
191*7c568831SAndroid Build Coastguard Worker 
192*7c568831SAndroid Build Coastguard Worker     xmlFreeDoc(doc);
193*7c568831SAndroid Build Coastguard Worker     xmlFuzzDataCleanup();
194*7c568831SAndroid Build Coastguard Worker 
195*7c568831SAndroid Build Coastguard Worker     return(ret);
196*7c568831SAndroid Build Coastguard Worker }
197*7c568831SAndroid Build Coastguard Worker #endif
198*7c568831SAndroid Build Coastguard Worker 
199*7c568831SAndroid Build Coastguard Worker int
main(void)200*7c568831SAndroid Build Coastguard Worker main(void) {
201*7c568831SAndroid Build Coastguard Worker     int ret = 0;
202*7c568831SAndroid Build Coastguard Worker 
203*7c568831SAndroid Build Coastguard Worker #ifdef HAVE_XML_FUZZER
204*7c568831SAndroid Build Coastguard Worker     if (testEntityLoader() != 0)
205*7c568831SAndroid Build Coastguard Worker         ret = 1;
206*7c568831SAndroid Build Coastguard Worker #endif
207*7c568831SAndroid Build Coastguard Worker #ifdef HAVE_HTML_FUZZER
208*7c568831SAndroid Build Coastguard Worker     if (testFuzzer(fuzzHtmlInit, fuzzHtml, "seed/html/*") != 0)
209*7c568831SAndroid Build Coastguard Worker         ret = 1;
210*7c568831SAndroid Build Coastguard Worker #endif
211*7c568831SAndroid Build Coastguard Worker #ifdef HAVE_READER_FUZZER
212*7c568831SAndroid Build Coastguard Worker     if (testFuzzer(fuzzReaderInit, fuzzReader, "seed/reader/*") != 0)
213*7c568831SAndroid Build Coastguard Worker         ret = 1;
214*7c568831SAndroid Build Coastguard Worker #endif
215*7c568831SAndroid Build Coastguard Worker #ifdef HAVE_REGEXP_FUZZER
216*7c568831SAndroid Build Coastguard Worker     if (testFuzzer(fuzzRegexpInit, fuzzRegexp, "seed/regexp/*") != 0)
217*7c568831SAndroid Build Coastguard Worker         ret = 1;
218*7c568831SAndroid Build Coastguard Worker #endif
219*7c568831SAndroid Build Coastguard Worker #ifdef HAVE_SCHEMA_FUZZER
220*7c568831SAndroid Build Coastguard Worker     if (testFuzzer(fuzzSchemaInit, fuzzSchema, "seed/schema/*") != 0)
221*7c568831SAndroid Build Coastguard Worker         ret = 1;
222*7c568831SAndroid Build Coastguard Worker #endif
223*7c568831SAndroid Build Coastguard Worker #ifdef HAVE_URI_FUZZER
224*7c568831SAndroid Build Coastguard Worker     if (testFuzzer(fuzzUriInit, fuzzUri, "seed/uri/*") != 0)
225*7c568831SAndroid Build Coastguard Worker         ret = 1;
226*7c568831SAndroid Build Coastguard Worker #endif
227*7c568831SAndroid Build Coastguard Worker #ifdef HAVE_VALID_FUZZER
228*7c568831SAndroid Build Coastguard Worker     if (testFuzzer(fuzzValidInit, fuzzValid, "seed/valid/*") != 0)
229*7c568831SAndroid Build Coastguard Worker         ret = 1;
230*7c568831SAndroid Build Coastguard Worker #endif
231*7c568831SAndroid Build Coastguard Worker #ifdef HAVE_XINCLUDE_FUZZER
232*7c568831SAndroid Build Coastguard Worker     if (testFuzzer(fuzzXIncludeInit, fuzzXInclude, "seed/xinclude/*") != 0)
233*7c568831SAndroid Build Coastguard Worker         ret = 1;
234*7c568831SAndroid Build Coastguard Worker #endif
235*7c568831SAndroid Build Coastguard Worker #ifdef HAVE_XML_FUZZER
236*7c568831SAndroid Build Coastguard Worker     if (testFuzzer(fuzzXmlInit, fuzzXml, "seed/xml/*") != 0)
237*7c568831SAndroid Build Coastguard Worker         ret = 1;
238*7c568831SAndroid Build Coastguard Worker #endif
239*7c568831SAndroid Build Coastguard Worker #ifdef HAVE_XPATH_FUZZER
240*7c568831SAndroid Build Coastguard Worker     if (testFuzzer(fuzzXPathInit, fuzzXPath, "seed/xpath/*") != 0)
241*7c568831SAndroid Build Coastguard Worker         ret = 1;
242*7c568831SAndroid Build Coastguard Worker #endif
243*7c568831SAndroid Build Coastguard Worker 
244*7c568831SAndroid Build Coastguard Worker     if (ret == 0)
245*7c568831SAndroid Build Coastguard Worker         printf("Successfully tested %d inputs\n", numInputs);
246*7c568831SAndroid Build Coastguard Worker 
247*7c568831SAndroid Build Coastguard Worker     return(ret);
248*7c568831SAndroid Build Coastguard Worker }
249*7c568831SAndroid Build Coastguard Worker 
250