mirror of
https://gitlab.gnome.org/GNOME/libxml2.git
synced 2025-03-23 02:50:08 +03:00
fuzz: Check malloc failure reports in XML fuzzers
This commit is contained in:
parent
9684e7a0f2
commit
e115194e6f
@ -30,7 +30,7 @@ LLVMFuzzerTestOneInput(const char *data, size_t size) {
|
||||
if (size > 50000)
|
||||
return(0);
|
||||
|
||||
maxAlloc = xmlFuzzReadInt(4) % (size + 1);
|
||||
maxAlloc = xmlFuzzReadInt(4) % (size + 100);
|
||||
|
||||
xmlFuzzDataInit(data, size);
|
||||
xmlFuzzReadEntities();
|
||||
|
69
fuzz/valid.c
69
fuzz/valid.c
@ -27,6 +27,7 @@ LLVMFuzzerInitialize(int *argc ATTRIBUTE_UNUSED,
|
||||
|
||||
int
|
||||
LLVMFuzzerTestOneInput(const char *data, size_t size) {
|
||||
xmlParserCtxtPtr ctxt;
|
||||
xmlDocPtr doc;
|
||||
xmlValidCtxtPtr vctxt;
|
||||
const char *docBuffer, *docUrl;
|
||||
@ -37,7 +38,7 @@ LLVMFuzzerTestOneInput(const char *data, size_t size) {
|
||||
opts = (int) xmlFuzzReadInt(4);
|
||||
opts &= ~XML_PARSE_XINCLUDE;
|
||||
opts |= XML_PARSE_DTDVALID;
|
||||
maxAlloc = xmlFuzzReadInt(4) % (size + 1);
|
||||
maxAlloc = xmlFuzzReadInt(4) % (size + 100);
|
||||
|
||||
xmlFuzzReadEntities();
|
||||
docBuffer = xmlFuzzMainEntity(&docSize);
|
||||
@ -48,13 +49,20 @@ LLVMFuzzerTestOneInput(const char *data, size_t size) {
|
||||
/* Pull parser */
|
||||
|
||||
xmlFuzzMemSetLimit(maxAlloc);
|
||||
doc = xmlReadMemory(docBuffer, docSize, docUrl, NULL, opts);
|
||||
xmlFreeDoc(doc);
|
||||
ctxt = xmlNewParserCtxt();
|
||||
if (ctxt != NULL) {
|
||||
doc = xmlCtxtReadMemory(ctxt, docBuffer, docSize, docUrl, NULL, opts);
|
||||
xmlFuzzCheckMallocFailure("xmlCtxtReadMemory",
|
||||
ctxt->errNo == XML_ERR_NO_MEMORY);
|
||||
xmlFreeDoc(doc);
|
||||
xmlFreeParserCtxt(ctxt);
|
||||
}
|
||||
|
||||
/* Post validation */
|
||||
|
||||
xmlFuzzMemSetLimit(maxAlloc);
|
||||
doc = xmlReadMemory(docBuffer, docSize, docUrl, NULL, opts & ~XML_PARSE_DTDVALID);
|
||||
doc = xmlReadMemory(docBuffer, docSize, docUrl, NULL,
|
||||
opts & ~XML_PARSE_DTDVALID);
|
||||
vctxt = xmlNewValidCtxt();
|
||||
xmlValidateDocument(vctxt, doc);
|
||||
xmlFreeValidCtxt(vctxt);
|
||||
@ -65,25 +73,26 @@ LLVMFuzzerTestOneInput(const char *data, size_t size) {
|
||||
#ifdef LIBXML_PUSH_ENABLED
|
||||
{
|
||||
static const size_t maxChunkSize = 128;
|
||||
xmlParserCtxtPtr ctxt;
|
||||
size_t consumed, chunkSize;
|
||||
|
||||
xmlFuzzMemSetLimit(maxAlloc);
|
||||
ctxt = xmlCreatePushParserCtxt(NULL, NULL, NULL, 0, docUrl);
|
||||
if (ctxt == NULL)
|
||||
goto exit;
|
||||
xmlCtxtUseOptions(ctxt, opts);
|
||||
if (ctxt != 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);
|
||||
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);
|
||||
xmlFuzzCheckMallocFailure("xmlParseChunk",
|
||||
ctxt->errNo == XML_ERR_NO_MEMORY);
|
||||
xmlFreeDoc(ctxt->myDoc);
|
||||
xmlFreeParserCtxt(ctxt);
|
||||
}
|
||||
|
||||
xmlParseChunk(ctxt, NULL, 0, 1);
|
||||
xmlFreeDoc(ctxt->myDoc);
|
||||
xmlFreeParserCtxt(ctxt);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -92,24 +101,28 @@ LLVMFuzzerTestOneInput(const char *data, size_t size) {
|
||||
#ifdef LIBXML_READER_ENABLED
|
||||
{
|
||||
xmlTextReaderPtr reader;
|
||||
const xmlError *error;
|
||||
int j;
|
||||
|
||||
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);
|
||||
if (reader != NULL) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (j = 0; j < 10; j++)
|
||||
xmlTextReaderRead(reader);
|
||||
error = xmlTextReaderGetLastError(reader);
|
||||
xmlFuzzCheckMallocFailure("xmlTextReaderRead",
|
||||
error->code == XML_ERR_NO_MEMORY);
|
||||
xmlFreeTextReader(reader);
|
||||
}
|
||||
for (j = 0; j < 10; j++)
|
||||
xmlTextReaderRead(reader);
|
||||
xmlFreeTextReader(reader);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -28,6 +28,7 @@ LLVMFuzzerInitialize(int *argc ATTRIBUTE_UNUSED,
|
||||
|
||||
int
|
||||
LLVMFuzzerTestOneInput(const char *data, size_t size) {
|
||||
xmlParserCtxtPtr ctxt;
|
||||
xmlDocPtr doc;
|
||||
const char *docBuffer, *docUrl;
|
||||
size_t maxAlloc, docSize;
|
||||
@ -36,7 +37,7 @@ LLVMFuzzerTestOneInput(const char *data, size_t size) {
|
||||
xmlFuzzDataInit(data, size);
|
||||
opts = (int) xmlFuzzReadInt(4);
|
||||
opts |= XML_PARSE_XINCLUDE;
|
||||
maxAlloc = xmlFuzzReadInt(4) % (size + 1);
|
||||
maxAlloc = xmlFuzzReadInt(4) % (size + 100);
|
||||
|
||||
xmlFuzzReadEntities();
|
||||
docBuffer = xmlFuzzMainEntity(&docSize);
|
||||
@ -47,9 +48,35 @@ LLVMFuzzerTestOneInput(const char *data, size_t size) {
|
||||
/* Pull parser */
|
||||
|
||||
xmlFuzzMemSetLimit(maxAlloc);
|
||||
doc = xmlReadMemory(docBuffer, docSize, docUrl, NULL, opts);
|
||||
xmlXIncludeProcessFlags(doc, opts);
|
||||
xmlFreeDoc(doc);
|
||||
ctxt = xmlNewParserCtxt();
|
||||
if (ctxt != NULL) {
|
||||
xmlXIncludeCtxtPtr xinc;
|
||||
xmlDocPtr copy;
|
||||
|
||||
doc = xmlCtxtReadMemory(ctxt, docBuffer, docSize, docUrl, NULL, opts);
|
||||
xmlFuzzCheckMallocFailure("xmlCtxtReadMemory",
|
||||
ctxt->errNo == XML_ERR_NO_MEMORY);
|
||||
|
||||
xmlFuzzResetMallocFailed();
|
||||
xinc = xmlXIncludeNewContext(doc);
|
||||
xmlXIncludeSetFlags(xinc, opts);
|
||||
xmlXIncludeProcessNode(xinc, (xmlNodePtr) doc);
|
||||
if (doc != NULL) {
|
||||
xmlFuzzCheckMallocFailure("xmlXIncludeProcessNode",
|
||||
xinc == NULL ||
|
||||
xmlXIncludeGetLastError(xinc) == XML_ERR_NO_MEMORY);
|
||||
}
|
||||
xmlXIncludeFreeContext(xinc);
|
||||
|
||||
xmlFuzzResetMallocFailed();
|
||||
copy = xmlCopyDoc(doc, 1);
|
||||
if (doc != NULL)
|
||||
xmlFuzzCheckMallocFailure("xmlCopyNode", copy == NULL);
|
||||
xmlFreeDoc(copy);
|
||||
|
||||
xmlFreeDoc(doc);
|
||||
xmlFreeParserCtxt(ctxt);
|
||||
}
|
||||
|
||||
/* Reader */
|
||||
|
||||
|
91
fuzz/xml.c
91
fuzz/xml.c
@ -9,6 +9,7 @@
|
||||
#include <libxml/tree.h>
|
||||
#include <libxml/xmlerror.h>
|
||||
#include <libxml/xmlreader.h>
|
||||
#include <libxml/xmlsave.h>
|
||||
#include "fuzz.h"
|
||||
|
||||
int
|
||||
@ -27,6 +28,7 @@ LLVMFuzzerInitialize(int *argc ATTRIBUTE_UNUSED,
|
||||
|
||||
int
|
||||
LLVMFuzzerTestOneInput(const char *data, size_t size) {
|
||||
xmlParserCtxtPtr ctxt;
|
||||
xmlDocPtr doc;
|
||||
const char *docBuffer, *docUrl;
|
||||
size_t maxAlloc, docSize;
|
||||
@ -40,7 +42,7 @@ LLVMFuzzerTestOneInput(const char *data, size_t size) {
|
||||
opts &= ~XML_PARSE_XINCLUDE &
|
||||
~XML_PARSE_DTDVALID &
|
||||
~XML_PARSE_SAX1;
|
||||
maxAlloc = xmlFuzzReadInt(4) % (size + 1);
|
||||
maxAlloc = xmlFuzzReadInt(4) % (size + 100);
|
||||
|
||||
xmlFuzzReadEntities();
|
||||
docBuffer = xmlFuzzMainEntity(&docSize);
|
||||
@ -51,45 +53,62 @@ LLVMFuzzerTestOneInput(const char *data, size_t size) {
|
||||
/* Pull parser */
|
||||
|
||||
xmlFuzzMemSetLimit(maxAlloc);
|
||||
doc = xmlReadMemory(docBuffer, docSize, docUrl, NULL, opts);
|
||||
ctxt = xmlNewParserCtxt();
|
||||
if (ctxt != NULL) {
|
||||
doc = xmlCtxtReadMemory(ctxt, docBuffer, docSize, docUrl, NULL, opts);
|
||||
xmlFuzzCheckMallocFailure("xmlCtxtReadMemory",
|
||||
ctxt->errNo == XML_ERR_NO_MEMORY);
|
||||
|
||||
if (doc != NULL) {
|
||||
#ifdef LIBXML_OUTPUT_ENABLED
|
||||
{
|
||||
xmlChar *out;
|
||||
int outSize;
|
||||
xmlBufferPtr buffer;
|
||||
xmlSaveCtxtPtr save;
|
||||
|
||||
/* Also test the serializer. */
|
||||
xmlDocDumpMemory(doc, &out, &outSize);
|
||||
xmlFree(out);
|
||||
}
|
||||
/* Also test the serializer. */
|
||||
xmlFuzzResetMallocFailed();
|
||||
buffer = xmlBufferCreate();
|
||||
save = xmlSaveToBuffer(buffer, NULL, 0);
|
||||
if (save != NULL) {
|
||||
int errNo;
|
||||
|
||||
xmlSaveDoc(save, doc);
|
||||
errNo = xmlSaveFinish(save);
|
||||
xmlFuzzCheckMallocFailure("xmlDocDumpMemory",
|
||||
errNo == XML_ERR_NO_MEMORY);
|
||||
}
|
||||
xmlBufferFree(buffer);
|
||||
#endif
|
||||
xmlFreeDoc(doc);
|
||||
}
|
||||
|
||||
xmlFreeDoc(doc);
|
||||
xmlFreeParserCtxt(ctxt);
|
||||
}
|
||||
|
||||
/* Push parser */
|
||||
|
||||
#ifdef LIBXML_PUSH_ENABLED
|
||||
{
|
||||
static const size_t maxChunkSize = 128;
|
||||
xmlParserCtxtPtr ctxt;
|
||||
size_t consumed, chunkSize;
|
||||
|
||||
xmlFuzzMemSetLimit(maxAlloc);
|
||||
ctxt = xmlCreatePushParserCtxt(NULL, NULL, NULL, 0, docUrl);
|
||||
if (ctxt == NULL)
|
||||
goto exit;
|
||||
xmlCtxtUseOptions(ctxt, opts);
|
||||
if (ctxt != 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);
|
||||
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);
|
||||
xmlFuzzCheckMallocFailure("xmlParseChunk",
|
||||
ctxt->errNo == XML_ERR_NO_MEMORY);
|
||||
xmlFreeDoc(ctxt->myDoc);
|
||||
xmlFreeParserCtxt(ctxt);
|
||||
}
|
||||
|
||||
xmlParseChunk(ctxt, NULL, 0, 1);
|
||||
xmlFreeDoc(ctxt->myDoc);
|
||||
xmlFreeParserCtxt(ctxt);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -98,24 +117,28 @@ LLVMFuzzerTestOneInput(const char *data, size_t size) {
|
||||
#ifdef LIBXML_READER_ENABLED
|
||||
{
|
||||
xmlTextReaderPtr reader;
|
||||
const xmlError *error;
|
||||
int j;
|
||||
|
||||
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);
|
||||
if (reader != NULL) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (j = 0; j < 10; j++)
|
||||
xmlTextReaderRead(reader);
|
||||
error = xmlTextReaderGetLastError(reader);
|
||||
xmlFuzzCheckMallocFailure("xmlTextReaderRead",
|
||||
error->code == XML_ERR_NO_MEMORY);
|
||||
xmlFreeTextReader(reader);
|
||||
}
|
||||
for (j = 0; j < 10; j++)
|
||||
xmlTextReaderRead(reader);
|
||||
xmlFreeTextReader(reader);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user