1 /*
2 * xml.c: a libFuzzer target to test several XML parser interfaces.
3 *
4 * See Copyright for the status of this software.
5 */
6
7 #include <libxml/catalog.h>
8 #include <libxml/parser.h>
9 #include <libxml/tree.h>
10 #include <libxml/xmlerror.h>
11 #include <libxml/xmlreader.h>
12 #include "fuzz.h"
13
14 int
LLVMFuzzerInitialize(int * argc ATTRIBUTE_UNUSED,char *** argv ATTRIBUTE_UNUSED)15 LLVMFuzzerInitialize(int *argc ATTRIBUTE_UNUSED,
16 char ***argv ATTRIBUTE_UNUSED) {
17 xmlFuzzMemSetup();
18 xmlInitParser();
19 #ifdef LIBXML_CATALOG_ENABLED
20 xmlInitializeCatalog();
21 #endif
22 xmlSetGenericErrorFunc(NULL, xmlFuzzErrorFunc);
23 xmlSetExternalEntityLoader(xmlFuzzEntityLoader);
24
25 return 0;
26 }
27
28 int
LLVMFuzzerTestOneInput(const char * data,size_t size)29 LLVMFuzzerTestOneInput(const char *data, size_t size) {
30 static const size_t maxChunkSize = 128;
31 xmlDocPtr doc;
32 xmlParserCtxtPtr ctxt;
33 xmlTextReaderPtr reader;
34 xmlChar *out;
35 const char *docBuffer, *docUrl;
36 size_t maxAlloc, docSize, consumed, chunkSize;
37 int opts, outSize;
38
39 xmlFuzzDataInit(data, size);
40 opts = (int) xmlFuzzReadInt(4);
41 opts &= ~XML_PARSE_XINCLUDE & ~XML_PARSE_DTDVALID;
42 maxAlloc = xmlFuzzReadInt(4) % (size + 1);
43
44 xmlFuzzReadEntities();
45 docBuffer = xmlFuzzMainEntity(&docSize);
46 docUrl = xmlFuzzMainUrl();
47 if (docBuffer == NULL)
48 goto exit;
49
50 /* Pull parser */
51
52 xmlFuzzMemSetLimit(maxAlloc);
53 doc = xmlReadMemory(docBuffer, docSize, docUrl, NULL, opts);
54 /* Also test the serializer. */
55 xmlDocDumpMemory(doc, &out, &outSize);
56 xmlFree(out);
57 xmlFreeDoc(doc);
58
59 /* Push parser */
60
61 xmlFuzzMemSetLimit(maxAlloc);
62 ctxt = xmlCreatePushParserCtxt(NULL, NULL, NULL, 0, docUrl);
63 if (ctxt == NULL)
64 goto exit;
65 xmlCtxtUseOptions(ctxt, opts);
66
67 for (consumed = 0; consumed < docSize; consumed += chunkSize) {
68 chunkSize = docSize - consumed;
69 if (chunkSize > maxChunkSize)
70 chunkSize = maxChunkSize;
71 xmlParseChunk(ctxt, docBuffer + consumed, chunkSize, 0);
72 }
73
74 xmlParseChunk(ctxt, NULL, 0, 1);
75 xmlFreeDoc(ctxt->myDoc);
76 xmlFreeParserCtxt(ctxt);
77
78 /* Reader */
79
80 xmlFuzzMemSetLimit(maxAlloc);
81 reader = xmlReaderForMemory(docBuffer, docSize, NULL, NULL, opts);
82 if (reader == NULL)
83 goto exit;
84 while (xmlTextReaderRead(reader) == 1) {
85 if (xmlTextReaderNodeType(reader) == XML_ELEMENT_NODE) {
86 int i, n = xmlTextReaderAttributeCount(reader);
87 for (i=0; i<n; i++) {
88 xmlTextReaderMoveToAttributeNo(reader, i);
89 while (xmlTextReaderReadAttributeValue(reader) == 1);
90 }
91 }
92 }
93 xmlFreeTextReader(reader);
94
95 exit:
96 xmlFuzzMemSetLimit(0);
97 xmlFuzzDataCleanup();
98 xmlResetLastError();
99 return(0);
100 }
101
102