xref: /aosp_15_r20/external/libxml2/fuzz/html.c (revision 7c5688314b92172186c154356a6374bf7684c3ca)
1*7c568831SAndroid Build Coastguard Worker /*
2*7c568831SAndroid Build Coastguard Worker  * html.c: a libFuzzer target to test several HTML parser interfaces.
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/HTMLparser.h>
8*7c568831SAndroid Build Coastguard Worker #include <libxml/HTMLtree.h>
9*7c568831SAndroid Build Coastguard Worker #include <libxml/catalog.h>
10*7c568831SAndroid Build Coastguard Worker #include "fuzz.h"
11*7c568831SAndroid Build Coastguard Worker 
12*7c568831SAndroid Build Coastguard Worker int
LLVMFuzzerInitialize(int * argc ATTRIBUTE_UNUSED,char *** argv ATTRIBUTE_UNUSED)13*7c568831SAndroid Build Coastguard Worker LLVMFuzzerInitialize(int *argc ATTRIBUTE_UNUSED,
14*7c568831SAndroid Build Coastguard Worker                      char ***argv ATTRIBUTE_UNUSED) {
15*7c568831SAndroid Build Coastguard Worker     xmlFuzzMemSetup();
16*7c568831SAndroid Build Coastguard Worker     xmlInitParser();
17*7c568831SAndroid Build Coastguard Worker #ifdef LIBXML_CATALOG_ENABLED
18*7c568831SAndroid Build Coastguard Worker     xmlInitializeCatalog();
19*7c568831SAndroid Build Coastguard Worker     xmlCatalogSetDefaults(XML_CATA_ALLOW_NONE);
20*7c568831SAndroid Build Coastguard Worker #endif
21*7c568831SAndroid Build Coastguard Worker 
22*7c568831SAndroid Build Coastguard Worker     return 0;
23*7c568831SAndroid Build Coastguard Worker }
24*7c568831SAndroid Build Coastguard Worker 
25*7c568831SAndroid Build Coastguard Worker int
LLVMFuzzerTestOneInput(const char * data,size_t size)26*7c568831SAndroid Build Coastguard Worker LLVMFuzzerTestOneInput(const char *data, size_t size) {
27*7c568831SAndroid Build Coastguard Worker     xmlParserCtxtPtr ctxt;
28*7c568831SAndroid Build Coastguard Worker     htmlDocPtr doc;
29*7c568831SAndroid Build Coastguard Worker     const char *docBuffer;
30*7c568831SAndroid Build Coastguard Worker     size_t maxAlloc, docSize;
31*7c568831SAndroid Build Coastguard Worker     int opts;
32*7c568831SAndroid Build Coastguard Worker 
33*7c568831SAndroid Build Coastguard Worker     xmlFuzzDataInit(data, size);
34*7c568831SAndroid Build Coastguard Worker     opts = (int) xmlFuzzReadInt(4);
35*7c568831SAndroid Build Coastguard Worker     maxAlloc = xmlFuzzReadInt(4) % (size + 100);
36*7c568831SAndroid Build Coastguard Worker 
37*7c568831SAndroid Build Coastguard Worker     docBuffer = xmlFuzzReadRemaining(&docSize);
38*7c568831SAndroid Build Coastguard Worker     if (docBuffer == NULL) {
39*7c568831SAndroid Build Coastguard Worker         xmlFuzzDataCleanup();
40*7c568831SAndroid Build Coastguard Worker         return(0);
41*7c568831SAndroid Build Coastguard Worker     }
42*7c568831SAndroid Build Coastguard Worker 
43*7c568831SAndroid Build Coastguard Worker     /* Pull parser */
44*7c568831SAndroid Build Coastguard Worker 
45*7c568831SAndroid Build Coastguard Worker     xmlFuzzMemSetLimit(maxAlloc);
46*7c568831SAndroid Build Coastguard Worker     ctxt = htmlNewParserCtxt();
47*7c568831SAndroid Build Coastguard Worker     if (ctxt != NULL) {
48*7c568831SAndroid Build Coastguard Worker         xmlCtxtSetErrorHandler(ctxt, xmlFuzzSErrorFunc, NULL);
49*7c568831SAndroid Build Coastguard Worker         doc = htmlCtxtReadMemory(ctxt, docBuffer, docSize, NULL, NULL, opts);
50*7c568831SAndroid Build Coastguard Worker         xmlFuzzCheckMallocFailure("htmlCtxtReadMemory",
51*7c568831SAndroid Build Coastguard Worker                                   ctxt->errNo == XML_ERR_NO_MEMORY);
52*7c568831SAndroid Build Coastguard Worker 
53*7c568831SAndroid Build Coastguard Worker         if (doc != NULL) {
54*7c568831SAndroid Build Coastguard Worker             xmlDocPtr copy;
55*7c568831SAndroid Build Coastguard Worker 
56*7c568831SAndroid Build Coastguard Worker #ifdef LIBXML_OUTPUT_ENABLED
57*7c568831SAndroid Build Coastguard Worker             xmlOutputBufferPtr out;
58*7c568831SAndroid Build Coastguard Worker             const xmlChar *content;
59*7c568831SAndroid Build Coastguard Worker 
60*7c568831SAndroid Build Coastguard Worker             /*
61*7c568831SAndroid Build Coastguard Worker              * Also test the serializer. Call htmlDocContentDumpOutput with our
62*7c568831SAndroid Build Coastguard Worker              * own buffer to avoid encoding the output. The HTML encoding is
63*7c568831SAndroid Build Coastguard Worker              * excruciatingly slow (see htmlEntityValueLookup).
64*7c568831SAndroid Build Coastguard Worker              */
65*7c568831SAndroid Build Coastguard Worker             out = xmlAllocOutputBuffer(NULL);
66*7c568831SAndroid Build Coastguard Worker             htmlDocContentDumpOutput(out, doc, NULL);
67*7c568831SAndroid Build Coastguard Worker             content = xmlOutputBufferGetContent(out);
68*7c568831SAndroid Build Coastguard Worker             xmlOutputBufferClose(out);
69*7c568831SAndroid Build Coastguard Worker             xmlFuzzCheckMallocFailure("htmlDocContentDumpOutput",
70*7c568831SAndroid Build Coastguard Worker                                       content == NULL);
71*7c568831SAndroid Build Coastguard Worker #endif
72*7c568831SAndroid Build Coastguard Worker 
73*7c568831SAndroid Build Coastguard Worker             copy = xmlCopyDoc(doc, 1);
74*7c568831SAndroid Build Coastguard Worker             xmlFuzzCheckMallocFailure("xmlCopyNode", copy == NULL);
75*7c568831SAndroid Build Coastguard Worker             xmlFreeDoc(copy);
76*7c568831SAndroid Build Coastguard Worker 
77*7c568831SAndroid Build Coastguard Worker             xmlFreeDoc(doc);
78*7c568831SAndroid Build Coastguard Worker         }
79*7c568831SAndroid Build Coastguard Worker 
80*7c568831SAndroid Build Coastguard Worker         htmlFreeParserCtxt(ctxt);
81*7c568831SAndroid Build Coastguard Worker     }
82*7c568831SAndroid Build Coastguard Worker 
83*7c568831SAndroid Build Coastguard Worker 
84*7c568831SAndroid Build Coastguard Worker     /* Push parser */
85*7c568831SAndroid Build Coastguard Worker 
86*7c568831SAndroid Build Coastguard Worker #ifdef LIBXML_PUSH_ENABLED
87*7c568831SAndroid Build Coastguard Worker     {
88*7c568831SAndroid Build Coastguard Worker         static const size_t maxChunkSize = 128;
89*7c568831SAndroid Build Coastguard Worker         size_t consumed, chunkSize;
90*7c568831SAndroid Build Coastguard Worker 
91*7c568831SAndroid Build Coastguard Worker         xmlFuzzMemSetLimit(maxAlloc);
92*7c568831SAndroid Build Coastguard Worker         ctxt = htmlCreatePushParserCtxt(NULL, NULL, NULL, 0, NULL,
93*7c568831SAndroid Build Coastguard Worker                                         XML_CHAR_ENCODING_NONE);
94*7c568831SAndroid Build Coastguard Worker 
95*7c568831SAndroid Build Coastguard Worker         if (ctxt != NULL) {
96*7c568831SAndroid Build Coastguard Worker             xmlCtxtSetErrorHandler(ctxt, xmlFuzzSErrorFunc, NULL);
97*7c568831SAndroid Build Coastguard Worker             htmlCtxtUseOptions(ctxt, opts);
98*7c568831SAndroid Build Coastguard Worker 
99*7c568831SAndroid Build Coastguard Worker             for (consumed = 0; consumed < docSize; consumed += chunkSize) {
100*7c568831SAndroid Build Coastguard Worker                 chunkSize = docSize - consumed;
101*7c568831SAndroid Build Coastguard Worker                 if (chunkSize > maxChunkSize)
102*7c568831SAndroid Build Coastguard Worker                     chunkSize = maxChunkSize;
103*7c568831SAndroid Build Coastguard Worker                 htmlParseChunk(ctxt, docBuffer + consumed, chunkSize, 0);
104*7c568831SAndroid Build Coastguard Worker             }
105*7c568831SAndroid Build Coastguard Worker 
106*7c568831SAndroid Build Coastguard Worker             htmlParseChunk(ctxt, NULL, 0, 1);
107*7c568831SAndroid Build Coastguard Worker             xmlFuzzCheckMallocFailure("htmlParseChunk",
108*7c568831SAndroid Build Coastguard Worker                                       ctxt->errNo == XML_ERR_NO_MEMORY);
109*7c568831SAndroid Build Coastguard Worker             xmlFreeDoc(ctxt->myDoc);
110*7c568831SAndroid Build Coastguard Worker             htmlFreeParserCtxt(ctxt);
111*7c568831SAndroid Build Coastguard Worker         }
112*7c568831SAndroid Build Coastguard Worker     }
113*7c568831SAndroid Build Coastguard Worker #endif
114*7c568831SAndroid Build Coastguard Worker 
115*7c568831SAndroid Build Coastguard Worker     /* Cleanup */
116*7c568831SAndroid Build Coastguard Worker 
117*7c568831SAndroid Build Coastguard Worker     xmlFuzzMemSetLimit(0);
118*7c568831SAndroid Build Coastguard Worker     xmlFuzzDataCleanup();
119*7c568831SAndroid Build Coastguard Worker     xmlResetLastError();
120*7c568831SAndroid Build Coastguard Worker 
121*7c568831SAndroid Build Coastguard Worker     return(0);
122*7c568831SAndroid Build Coastguard Worker }
123*7c568831SAndroid Build Coastguard Worker 
124