1*7c568831SAndroid Build Coastguard Worker /*
2*7c568831SAndroid Build Coastguard Worker * valid.c: a libFuzzer target to test DTD validation.
3*7c568831SAndroid Build Coastguard Worker *
4*7c568831SAndroid Build Coastguard Worker * See Copyright for the status of this software.
5*7c568831SAndroid Build Coastguard Worker */
6*7c568831SAndroid Build Coastguard Worker
7*7c568831SAndroid Build Coastguard Worker #include <libxml/catalog.h>
8*7c568831SAndroid Build Coastguard Worker #include <libxml/parser.h>
9*7c568831SAndroid Build Coastguard Worker #include <libxml/tree.h>
10*7c568831SAndroid Build Coastguard Worker #include <libxml/xmlerror.h>
11*7c568831SAndroid Build Coastguard Worker #include "fuzz.h"
12*7c568831SAndroid Build Coastguard Worker
13*7c568831SAndroid Build Coastguard Worker int
LLVMFuzzerInitialize(int * argc ATTRIBUTE_UNUSED,char *** argv ATTRIBUTE_UNUSED)14*7c568831SAndroid Build Coastguard Worker LLVMFuzzerInitialize(int *argc ATTRIBUTE_UNUSED,
15*7c568831SAndroid Build Coastguard Worker char ***argv ATTRIBUTE_UNUSED) {
16*7c568831SAndroid Build Coastguard Worker xmlFuzzMemSetup();
17*7c568831SAndroid Build Coastguard Worker xmlInitParser();
18*7c568831SAndroid Build Coastguard Worker #ifdef LIBXML_CATALOG_ENABLED
19*7c568831SAndroid Build Coastguard Worker xmlInitializeCatalog();
20*7c568831SAndroid Build Coastguard Worker xmlCatalogSetDefaults(XML_CATA_ALLOW_NONE);
21*7c568831SAndroid Build Coastguard Worker #endif
22*7c568831SAndroid Build Coastguard Worker
23*7c568831SAndroid Build Coastguard Worker return 0;
24*7c568831SAndroid Build Coastguard Worker }
25*7c568831SAndroid Build Coastguard Worker
26*7c568831SAndroid Build Coastguard Worker int
LLVMFuzzerTestOneInput(const char * data,size_t size)27*7c568831SAndroid Build Coastguard Worker LLVMFuzzerTestOneInput(const char *data, size_t size) {
28*7c568831SAndroid Build Coastguard Worker xmlParserCtxtPtr ctxt;
29*7c568831SAndroid Build Coastguard Worker xmlDocPtr doc;
30*7c568831SAndroid Build Coastguard Worker xmlValidCtxtPtr vctxt;
31*7c568831SAndroid Build Coastguard Worker const char *docBuffer, *docUrl;
32*7c568831SAndroid Build Coastguard Worker size_t maxAlloc, docSize;
33*7c568831SAndroid Build Coastguard Worker int opts;
34*7c568831SAndroid Build Coastguard Worker
35*7c568831SAndroid Build Coastguard Worker xmlFuzzDataInit(data, size);
36*7c568831SAndroid Build Coastguard Worker opts = (int) xmlFuzzReadInt(4);
37*7c568831SAndroid Build Coastguard Worker opts &= ~XML_PARSE_XINCLUDE;
38*7c568831SAndroid Build Coastguard Worker opts |= XML_PARSE_DTDVALID;
39*7c568831SAndroid Build Coastguard Worker maxAlloc = xmlFuzzReadInt(4) % (size + 100);
40*7c568831SAndroid Build Coastguard Worker
41*7c568831SAndroid Build Coastguard Worker xmlFuzzReadEntities();
42*7c568831SAndroid Build Coastguard Worker docBuffer = xmlFuzzMainEntity(&docSize);
43*7c568831SAndroid Build Coastguard Worker docUrl = xmlFuzzMainUrl();
44*7c568831SAndroid Build Coastguard Worker if (docBuffer == NULL)
45*7c568831SAndroid Build Coastguard Worker goto exit;
46*7c568831SAndroid Build Coastguard Worker
47*7c568831SAndroid Build Coastguard Worker /* Pull parser */
48*7c568831SAndroid Build Coastguard Worker
49*7c568831SAndroid Build Coastguard Worker xmlFuzzMemSetLimit(maxAlloc);
50*7c568831SAndroid Build Coastguard Worker ctxt = xmlNewParserCtxt();
51*7c568831SAndroid Build Coastguard Worker if (ctxt != NULL) {
52*7c568831SAndroid Build Coastguard Worker xmlCtxtSetErrorHandler(ctxt, xmlFuzzSErrorFunc, NULL);
53*7c568831SAndroid Build Coastguard Worker xmlCtxtSetResourceLoader(ctxt, xmlFuzzResourceLoader, NULL);
54*7c568831SAndroid Build Coastguard Worker doc = xmlCtxtReadMemory(ctxt, docBuffer, docSize, docUrl, NULL, opts);
55*7c568831SAndroid Build Coastguard Worker xmlFuzzCheckMallocFailure("xmlCtxtReadMemory",
56*7c568831SAndroid Build Coastguard Worker ctxt->errNo == XML_ERR_NO_MEMORY);
57*7c568831SAndroid Build Coastguard Worker xmlFreeDoc(doc);
58*7c568831SAndroid Build Coastguard Worker xmlFreeParserCtxt(ctxt);
59*7c568831SAndroid Build Coastguard Worker }
60*7c568831SAndroid Build Coastguard Worker
61*7c568831SAndroid Build Coastguard Worker /* Post validation */
62*7c568831SAndroid Build Coastguard Worker
63*7c568831SAndroid Build Coastguard Worker xmlFuzzMemSetLimit(maxAlloc);
64*7c568831SAndroid Build Coastguard Worker ctxt = xmlNewParserCtxt();
65*7c568831SAndroid Build Coastguard Worker if (ctxt != NULL) {
66*7c568831SAndroid Build Coastguard Worker xmlCtxtSetErrorHandler(ctxt, xmlFuzzSErrorFunc, NULL);
67*7c568831SAndroid Build Coastguard Worker xmlCtxtSetResourceLoader(ctxt, xmlFuzzResourceLoader, NULL);
68*7c568831SAndroid Build Coastguard Worker doc = xmlCtxtReadMemory(ctxt, docBuffer, docSize, docUrl, NULL,
69*7c568831SAndroid Build Coastguard Worker opts & ~XML_PARSE_DTDVALID);
70*7c568831SAndroid Build Coastguard Worker xmlFreeParserCtxt(ctxt);
71*7c568831SAndroid Build Coastguard Worker
72*7c568831SAndroid Build Coastguard Worker /* Post validation requires global callbacks */
73*7c568831SAndroid Build Coastguard Worker xmlSetGenericErrorFunc(NULL, xmlFuzzErrorFunc);
74*7c568831SAndroid Build Coastguard Worker xmlSetExternalEntityLoader(xmlFuzzEntityLoader);
75*7c568831SAndroid Build Coastguard Worker vctxt = xmlNewValidCtxt();
76*7c568831SAndroid Build Coastguard Worker xmlValidateDocument(vctxt, doc);
77*7c568831SAndroid Build Coastguard Worker xmlFreeValidCtxt(vctxt);
78*7c568831SAndroid Build Coastguard Worker xmlFreeDoc(doc);
79*7c568831SAndroid Build Coastguard Worker xmlSetGenericErrorFunc(NULL, NULL);
80*7c568831SAndroid Build Coastguard Worker xmlSetExternalEntityLoader(NULL);
81*7c568831SAndroid Build Coastguard Worker }
82*7c568831SAndroid Build Coastguard Worker
83*7c568831SAndroid Build Coastguard Worker /* Push parser */
84*7c568831SAndroid Build Coastguard Worker
85*7c568831SAndroid Build Coastguard Worker #ifdef LIBXML_PUSH_ENABLED
86*7c568831SAndroid Build Coastguard Worker {
87*7c568831SAndroid Build Coastguard Worker static const size_t maxChunkSize = 128;
88*7c568831SAndroid Build Coastguard Worker size_t consumed, chunkSize;
89*7c568831SAndroid Build Coastguard Worker
90*7c568831SAndroid Build Coastguard Worker xmlFuzzMemSetLimit(maxAlloc);
91*7c568831SAndroid Build Coastguard Worker ctxt = xmlCreatePushParserCtxt(NULL, NULL, NULL, 0, docUrl);
92*7c568831SAndroid Build Coastguard Worker if (ctxt != NULL) {
93*7c568831SAndroid Build Coastguard Worker xmlCtxtSetErrorHandler(ctxt, xmlFuzzSErrorFunc, NULL);
94*7c568831SAndroid Build Coastguard Worker xmlCtxtSetResourceLoader(ctxt, xmlFuzzResourceLoader, NULL);
95*7c568831SAndroid Build Coastguard Worker xmlCtxtUseOptions(ctxt, opts);
96*7c568831SAndroid Build Coastguard Worker
97*7c568831SAndroid Build Coastguard Worker for (consumed = 0; consumed < docSize; consumed += chunkSize) {
98*7c568831SAndroid Build Coastguard Worker chunkSize = docSize - consumed;
99*7c568831SAndroid Build Coastguard Worker if (chunkSize > maxChunkSize)
100*7c568831SAndroid Build Coastguard Worker chunkSize = maxChunkSize;
101*7c568831SAndroid Build Coastguard Worker xmlParseChunk(ctxt, docBuffer + consumed, chunkSize, 0);
102*7c568831SAndroid Build Coastguard Worker }
103*7c568831SAndroid Build Coastguard Worker
104*7c568831SAndroid Build Coastguard Worker xmlParseChunk(ctxt, NULL, 0, 1);
105*7c568831SAndroid Build Coastguard Worker xmlFuzzCheckMallocFailure("xmlParseChunk",
106*7c568831SAndroid Build Coastguard Worker ctxt->errNo == XML_ERR_NO_MEMORY);
107*7c568831SAndroid Build Coastguard Worker xmlFreeDoc(ctxt->myDoc);
108*7c568831SAndroid Build Coastguard Worker xmlFreeParserCtxt(ctxt);
109*7c568831SAndroid Build Coastguard Worker }
110*7c568831SAndroid Build Coastguard Worker }
111*7c568831SAndroid Build Coastguard Worker #endif
112*7c568831SAndroid Build Coastguard Worker
113*7c568831SAndroid Build Coastguard Worker exit:
114*7c568831SAndroid Build Coastguard Worker xmlFuzzMemSetLimit(0);
115*7c568831SAndroid Build Coastguard Worker xmlFuzzDataCleanup();
116*7c568831SAndroid Build Coastguard Worker xmlResetLastError();
117*7c568831SAndroid Build Coastguard Worker return(0);
118*7c568831SAndroid Build Coastguard Worker }
119*7c568831SAndroid Build Coastguard Worker
120