diff --git a/fuzz/schema.c b/fuzz/schema.c index 04e92f92..e87670a0 100644 --- a/fuzz/schema.c +++ b/fuzz/schema.c @@ -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(); diff --git a/fuzz/valid.c b/fuzz/valid.c index 264e9035..2b8782f4 100644 --- a/fuzz/valid.c +++ b/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; icode == XML_ERR_NO_MEMORY); + xmlFreeTextReader(reader); } - for (j = 0; j < 10; j++) - xmlTextReaderRead(reader); - xmlFreeTextReader(reader); } #endif diff --git a/fuzz/xinclude.c b/fuzz/xinclude.c index 3789ca57..cd0b564d 100644 --- a/fuzz/xinclude.c +++ b/fuzz/xinclude.c @@ -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 */ diff --git a/fuzz/xml.c b/fuzz/xml.c index bbe05c92..3955d245 100644 --- a/fuzz/xml.c +++ b/fuzz/xml.c @@ -9,6 +9,7 @@ #include #include #include +#include #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; icode == XML_ERR_NO_MEMORY); + xmlFreeTextReader(reader); } - for (j = 0; j < 10; j++) - xmlTextReaderRead(reader); - xmlFreeTextReader(reader); } #endif