1
0
mirror of https://gitlab.gnome.org/GNOME/libxml2.git synced 2024-12-23 17:33:50 +03:00

fuzz: Allow to fuzz without push, reader or output modules

This commit is contained in:
Nick Wellnhofer 2023-09-21 13:05:49 +02:00
parent fe1bfb349b
commit f9d717af97
7 changed files with 165 additions and 124 deletions

View File

@ -15,7 +15,7 @@
extern "C" {
#endif
#if defined(LIBXML_HTML_ENABLED) && defined(LIBXML_OUTPUT_ENABLED)
#if defined(LIBXML_HTML_ENABLED)
#define HAVE_HTML_FUZZER
#endif
#if defined(LIBXML_REGEXP_ENABLED)
@ -27,16 +27,13 @@ extern "C" {
#if 1
#define HAVE_URI_FUZZER
#endif
#if defined(LIBXML_VALID_ENABLED) && \
defined(LIBXML_READER_ENABLED)
#if defined(LIBXML_VALID_ENABLED)
#define HAVE_VALID_FUZZER
#endif
#if defined(LIBXML_XINCLUDE_ENABLED) && \
defined(LIBXML_READER_ENABLED)
#if defined(LIBXML_XINCLUDE_ENABLED)
#define HAVE_XINCLUDE_FUZZER
#endif
#if defined(LIBXML_OUTPUT_ENABLED) && \
defined(LIBXML_READER_ENABLED)
#if 1
#define HAVE_XML_FUZZER
#endif
#if defined(LIBXML_XPTR_ENABLED)

View File

@ -120,7 +120,9 @@ processXml(const char *docFile, FILE *out) {
fuzzRecorderInit(out);
doc = xmlReadFile(docFile, NULL, opts);
#ifdef LIBXML_XINCLUDE_ENABLED
xmlXIncludeProcessFlags(doc, opts);
#endif
xmlFreeDoc(doc);
fuzzRecorderCleanup();

View File

@ -24,19 +24,11 @@ LLVMFuzzerInitialize(int *argc ATTRIBUTE_UNUSED,
int
LLVMFuzzerTestOneInput(const char *data, size_t size) {
static const size_t maxChunkSize = 128;
htmlDocPtr doc;
htmlParserCtxtPtr ctxt;
xmlOutputBufferPtr out;
const char *docBuffer;
size_t maxAlloc, docSize, consumed, chunkSize;
size_t maxAlloc, docSize;
int opts;
(void) maxChunkSize;
(void) ctxt;
(void) consumed;
(void) chunkSize;
xmlFuzzDataInit(data, size);
opts = (int) xmlFuzzReadInt(4);
maxAlloc = xmlFuzzReadInt(4) % (size + 1);
@ -52,37 +44,49 @@ LLVMFuzzerTestOneInput(const char *data, size_t size) {
xmlFuzzMemSetLimit(maxAlloc);
doc = htmlReadMemory(docBuffer, docSize, NULL, NULL, opts);
/*
* Also test the serializer. Call htmlDocContentDumpOutput with our
* own buffer to avoid encoding the output. The HTML encoding is
* excruciatingly slow (see htmlEntityValueLookup).
*/
out = xmlAllocOutputBuffer(NULL);
htmlDocContentDumpOutput(out, doc, NULL);
xmlOutputBufferClose(out);
#ifdef LIBXML_OUTPUT_ENABLED
{
xmlOutputBufferPtr out;
/*
* Also test the serializer. Call htmlDocContentDumpOutput with our
* own buffer to avoid encoding the output. The HTML encoding is
* excruciatingly slow (see htmlEntityValueLookup).
*/
out = xmlAllocOutputBuffer(NULL);
htmlDocContentDumpOutput(out, doc, NULL);
xmlOutputBufferClose(out);
}
#endif
xmlFreeDoc(doc);
/* Push parser */
#ifdef LIBXML_PUSH_ENABLED
xmlFuzzMemSetLimit(maxAlloc);
ctxt = htmlCreatePushParserCtxt(NULL, NULL, NULL, 0, NULL,
XML_CHAR_ENCODING_NONE);
{
static const size_t maxChunkSize = 128;
xmlParserCtxtPtr ctxt;
size_t consumed, chunkSize;
if (ctxt != NULL) {
htmlCtxtUseOptions(ctxt, opts);
xmlFuzzMemSetLimit(maxAlloc);
ctxt = htmlCreatePushParserCtxt(NULL, NULL, NULL, 0, NULL,
XML_CHAR_ENCODING_NONE);
for (consumed = 0; consumed < docSize; consumed += chunkSize) {
chunkSize = docSize - consumed;
if (chunkSize > maxChunkSize)
chunkSize = maxChunkSize;
htmlParseChunk(ctxt, docBuffer + consumed, chunkSize, 0);
if (ctxt != NULL) {
htmlCtxtUseOptions(ctxt, opts);
for (consumed = 0; consumed < docSize; consumed += chunkSize) {
chunkSize = docSize - consumed;
if (chunkSize > maxChunkSize)
chunkSize = maxChunkSize;
htmlParseChunk(ctxt, docBuffer + consumed, chunkSize, 0);
}
htmlParseChunk(ctxt, NULL, 0, 1);
xmlFreeDoc(ctxt->myDoc);
htmlFreeParserCtxt(ctxt);
}
htmlParseChunk(ctxt, NULL, 0, 1);
xmlFreeDoc(ctxt->myDoc);
htmlFreeParserCtxt(ctxt);
}
#endif

View File

@ -147,14 +147,9 @@ testEntityLoader(void) {
"<!ENTITY ent SYSTEM \"ent.txt\">\\\n"
"ent.txt\\\n"
"Hello, world!\\\n";
static xmlChar expected[] =
"<?xml version=\"1.0\"?>\n"
"<!DOCTYPE doc SYSTEM \"doc.dtd\">\n"
"<doc>Hello, world!</doc>\n";
const char *docBuffer;
size_t docSize;
xmlDocPtr doc;
xmlChar *out;
int ret = 0;
xmlSetExternalEntityLoader(xmlFuzzEntityLoader);
@ -165,13 +160,23 @@ testEntityLoader(void) {
doc = xmlReadMemory(docBuffer, docSize, NULL, NULL,
XML_PARSE_NOENT | XML_PARSE_DTDLOAD);
xmlDocDumpMemory(doc, &out, NULL);
if (xmlStrcmp(out, expected) != 0) {
fprintf(stderr, "Expected:\n%sGot:\n%s", expected, out);
ret = 1;
}
#ifdef LIBXML_OUTPUT_ENABLED
{
static xmlChar expected[] =
"<?xml version=\"1.0\"?>\n"
"<!DOCTYPE doc SYSTEM \"doc.dtd\">\n"
"<doc>Hello, world!</doc>\n";
xmlChar *out;
xmlDocDumpMemory(doc, &out, NULL);
if (xmlStrcmp(out, expected) != 0) {
fprintf(stderr, "Expected:\n%sGot:\n%s", expected, out);
ret = 1;
}
xmlFree(out);
}
#endif
xmlFree(out);
xmlFreeDoc(doc);
xmlFuzzDataCleanup();

View File

@ -27,13 +27,10 @@ LLVMFuzzerInitialize(int *argc ATTRIBUTE_UNUSED,
int
LLVMFuzzerTestOneInput(const char *data, size_t size) {
static const size_t maxChunkSize = 128;
xmlDocPtr doc;
xmlParserCtxtPtr ctxt;
xmlValidCtxtPtr vctxt;
xmlTextReaderPtr reader;
const char *docBuffer, *docUrl;
size_t maxAlloc, docSize, consumed, chunkSize;
size_t maxAlloc, docSize;
int opts;
xmlFuzzDataInit(data, size);
@ -65,39 +62,53 @@ LLVMFuzzerTestOneInput(const char *data, size_t size) {
/* Push parser */
xmlFuzzMemSetLimit(maxAlloc);
ctxt = xmlCreatePushParserCtxt(NULL, NULL, NULL, 0, docUrl);
if (ctxt == NULL)
goto exit;
xmlCtxtUseOptions(ctxt, opts);
#ifdef LIBXML_PUSH_ENABLED
{
static const size_t maxChunkSize = 128;
xmlParserCtxtPtr ctxt;
size_t consumed, chunkSize;
for (consumed = 0; consumed < docSize; consumed += chunkSize) {
chunkSize = docSize - consumed;
if (chunkSize > maxChunkSize)
chunkSize = maxChunkSize;
xmlParseChunk(ctxt, docBuffer + consumed, chunkSize, 0);
xmlFuzzMemSetLimit(maxAlloc);
ctxt = xmlCreatePushParserCtxt(NULL, NULL, NULL, 0, docUrl);
if (ctxt == NULL)
goto exit;
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);
}
xmlParseChunk(ctxt, NULL, 0, 1);
xmlFreeDoc(ctxt->myDoc);
xmlFreeParserCtxt(ctxt);
#endif
/* Reader */
xmlFuzzMemSetLimit(maxAlloc);
reader = xmlReaderForMemory(docBuffer, docSize, NULL, NULL, opts);
if (reader == NULL)
goto exit;
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);
#ifdef LIBXML_READER_ENABLED
{
xmlTextReaderPtr reader;
xmlFuzzMemSetLimit(maxAlloc);
reader = xmlReaderForMemory(docBuffer, docSize, NULL, NULL, opts);
if (reader == NULL)
goto exit;
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);
}
xmlFreeTextReader(reader);
#endif
exit:
xmlFuzzMemSetLimit(0);

View File

@ -29,7 +29,6 @@ LLVMFuzzerInitialize(int *argc ATTRIBUTE_UNUSED,
int
LLVMFuzzerTestOneInput(const char *data, size_t size) {
xmlDocPtr doc;
xmlTextReaderPtr reader;
const char *docBuffer, *docUrl;
size_t maxAlloc, docSize;
int opts;
@ -55,20 +54,26 @@ LLVMFuzzerTestOneInput(const char *data, size_t size) {
/* Reader */
xmlFuzzMemSetLimit(maxAlloc);
reader = xmlReaderForMemory(docBuffer, docSize, NULL, NULL, opts);
if (reader == NULL)
goto exit;
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);
#ifdef LIBXML_READER_ENABLED
{
xmlTextReaderPtr reader;
xmlFuzzMemSetLimit(maxAlloc);
reader = xmlReaderForMemory(docBuffer, docSize, NULL, NULL, opts);
if (reader == NULL)
goto exit;
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);
}
xmlFreeTextReader(reader);
#endif
exit:
xmlFuzzMemSetLimit(0);

View File

@ -27,14 +27,10 @@ LLVMFuzzerInitialize(int *argc ATTRIBUTE_UNUSED,
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, *docUrl;
size_t maxAlloc, docSize, consumed, chunkSize;
int opts, outSize;
size_t maxAlloc, docSize;
int opts;
xmlFuzzDataInit(data, size);
opts = (int) xmlFuzzReadInt(4);
@ -51,48 +47,69 @@ LLVMFuzzerTestOneInput(const char *data, size_t size) {
xmlFuzzMemSetLimit(maxAlloc);
doc = xmlReadMemory(docBuffer, docSize, docUrl, NULL, opts);
/* Also test the serializer. */
xmlDocDumpMemory(doc, &out, &outSize);
xmlFree(out);
#ifdef LIBXML_OUTPUT_ENABLED
{
xmlChar *out;
int outSize;
/* Also test the serializer. */
xmlDocDumpMemory(doc, &out, &outSize);
xmlFree(out);
}
#endif
xmlFreeDoc(doc);
/* Push parser */
#ifdef LIBXML_PUSH_ENABLED
xmlFuzzMemSetLimit(maxAlloc);
ctxt = xmlCreatePushParserCtxt(NULL, NULL, NULL, 0, docUrl);
if (ctxt == NULL)
goto exit;
xmlCtxtUseOptions(ctxt, opts);
{
static const size_t maxChunkSize = 128;
xmlParserCtxtPtr ctxt;
size_t consumed, chunkSize;
for (consumed = 0; consumed < docSize; consumed += chunkSize) {
chunkSize = docSize - consumed;
if (chunkSize > maxChunkSize)
chunkSize = maxChunkSize;
xmlParseChunk(ctxt, docBuffer + consumed, chunkSize, 0);
xmlFuzzMemSetLimit(maxAlloc);
ctxt = xmlCreatePushParserCtxt(NULL, NULL, NULL, 0, docUrl);
if (ctxt == NULL)
goto exit;
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);
}
#endif
xmlParseChunk(ctxt, NULL, 0, 1);
xmlFreeDoc(ctxt->myDoc);
xmlFreeParserCtxt(ctxt);
/* Reader */
xmlFuzzMemSetLimit(maxAlloc);
reader = xmlReaderForMemory(docBuffer, docSize, NULL, NULL, opts);
if (reader == NULL)
goto exit;
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);
#ifdef LIBXML_READER_ENABLED
{
xmlTextReaderPtr reader;
xmlFuzzMemSetLimit(maxAlloc);
reader = xmlReaderForMemory(docBuffer, docSize, NULL, NULL, opts);
if (reader == NULL)
goto exit;
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);
}
xmlFreeTextReader(reader);
#endif
exit:
xmlFuzzMemSetLimit(0);