xref: /aosp_15_r20/external/libxml2/fuzz/valid.c (revision 7c5688314b92172186c154356a6374bf7684c3ca)
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