1
0
mirror of https://gitlab.gnome.org/GNOME/libxml2.git synced 2025-10-24 13:33:01 +03:00

Add a couple of libFuzzer targets

- XML fuzzer
  Currently tests the pull parser, push parser and reader, as well as
  serialization. Supports splitting fuzz data into multiple documents
  for things like external DTDs or entities. The seed corpus is built
  from parts of the test suite.

- Regexp fuzzer
  Seed corpus was statically generated from test suite.

- URI fuzzer
  Tests parsing and most other functions from uri.c.
This commit is contained in:
Nick Wellnhofer
2020-06-05 12:49:25 +02:00
parent 2e8cc66d8f
commit 00ed736eec
137 changed files with 850 additions and 2 deletions

90
fuzz/xml.c Normal file
View File

@@ -0,0 +1,90 @@
/*
* xml.c: a libFuzzer target to test several XML parser interfaces.
*
* See Copyright for the status of this software.
*/
#include <libxml/parser.h>
#include <libxml/tree.h>
#include <libxml/xmlerror.h>
#include <libxml/xmlreader.h>
#include "fuzz.h"
int
LLVMFuzzerInitialize(int *argc ATTRIBUTE_UNUSED,
char ***argv ATTRIBUTE_UNUSED) {
xmlInitParser();
xmlSetGenericErrorFunc(NULL, xmlFuzzErrorFunc);
xmlSetExternalEntityLoader(xmlFuzzEntityLoader);
return 0;
}
int
LLVMFuzzerTestOneInput(const char *data, size_t size) {
static const size_t maxChunkSize = 128;
xmlDocPtr doc;
xmlParserCtxtPtr ctxt;
xmlTextReaderPtr reader;
xmlChar *out;
const char *docBuffer;
size_t docSize, consumed, chunkSize;
int opts, outSize;
xmlFuzzDataInit(data, size);
opts = xmlFuzzReadInt();
/* XML_PARSE_HUGE still causes timeouts. */
opts &= ~XML_PARSE_HUGE;
xmlFuzzReadEntities();
docBuffer = xmlFuzzMainEntity(&docSize);
if (docBuffer == NULL) {
xmlFuzzDataCleanup();
return(0);
}
/* Pull parser */
doc = xmlReadMemory(docBuffer, docSize, NULL, NULL, opts);
/* Also test the serializer. */
xmlDocDumpMemory(doc, &out, &outSize);
xmlFree(out);
xmlFreeDoc(doc);
/* Push parser */
ctxt = xmlCreatePushParserCtxt(NULL, NULL, NULL, 0, NULL);
xmlCtxtUseOptions(ctxt, opts);
for (consumed = 0; consumed < docSize; consumed += chunkSize) {
chunkSize = docSize - consumed;
if (chunkSize > maxChunkSize)
chunkSize = maxChunkSize;
xmlParseChunk(ctxt, docBuffer + consumed, chunkSize, 0);
}
xmlParseChunk(ctxt, NULL, 0, 1);
xmlFreeDoc(ctxt->myDoc);
xmlFreeParserCtxt(ctxt);
/* Reader */
reader = xmlReaderForMemory(docBuffer, docSize, NULL, NULL, opts);
while (xmlTextReaderRead(reader) == 1) {
if (xmlTextReaderNodeType(reader) == XML_ELEMENT_NODE) {
int i, n = xmlTextReaderAttributeCount(reader);
for (i=0; i<n; i++) {
xmlTextReaderMoveToAttributeNo(reader, i);
while (xmlTextReaderReadAttributeValue(reader) == 1);
}
}
}
xmlFreeTextReader(reader);
/* Cleanup */
xmlFuzzDataCleanup();
return(0);
}