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