[libxml2] Test fuzz targets with dummy driver



commit 0d9da0290c0230802b31f9d9318ec0711ef0c43a
Author: Nick Wellnhofer <wellnhofer aevum de>
Date:   Mon Aug 24 03:16:25 2020 +0200

    Test fuzz targets with dummy driver
    
    Run fuzz targets with files in seed corpus during test.

 fuzz/Makefile.am  |   6 ++-
 fuzz/fuzz.c       |  32 ++++++++++++++++
 fuzz/fuzz.h       |   4 ++
 fuzz/testFuzzer.c | 109 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
 fuzz/xpathSeed.c  |  22 +----------
 5 files changed, 149 insertions(+), 24 deletions(-)
---
diff --git a/fuzz/Makefile.am b/fuzz/Makefile.am
index feba65be3..7f0bcef76 100644
--- a/fuzz/Makefile.am
+++ b/fuzz/Makefile.am
@@ -21,9 +21,11 @@ XML_SEED_CORPUS_SRC = \
 
 testFuzzer_SOURCES = testFuzzer.c fuzz.c
 
-.PHONY: tests clean-corpus
+.PHONY: tests corpus clean-corpus
 
-tests: testFuzzer$(EXEEXT)
+corpus: seed/html.stamp seed/schema.stamp seed/xml.stamp seed/xpath.stamp
+
+tests: testFuzzer$(EXEEXT) corpus
        @echo "## Running fuzzer tests"
        @./testFuzzer$(EXEEXT)
 
diff --git a/fuzz/fuzz.c b/fuzz/fuzz.c
index 0155efe50..543235c48 100644
--- a/fuzz/fuzz.c
+++ b/fuzz/fuzz.c
@@ -4,8 +4,11 @@
  * See Copyright for the status of this software.
  */
 
+#include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <sys/stat.h>
+
 #include <libxml/hash.h>
 #include <libxml/parser.h>
 #include <libxml/parserInternals.h>
@@ -361,3 +364,32 @@ xmlFuzzExtractStrings(const char *data, size_t size, char **strings,
     return(ret);
 }
 
+char *
+xmlSlurpFile(const char *path, size_t *sizeRet) {
+    FILE *file;
+    struct stat statbuf;
+    char *data;
+    size_t size;
+
+    if ((stat(path, &statbuf) != 0) || (!S_ISREG(statbuf.st_mode)))
+        return(NULL);
+    size = statbuf.st_size;
+    file = fopen(path, "rb");
+    if (file == NULL)
+        return(NULL);
+    data = xmlMalloc(size + 1);
+    if (data != NULL) {
+        if (fread(data, 1, size, file) != size) {
+            xmlFree(data);
+            data = NULL;
+        } else {
+            data[size] = 0;
+            if (sizeRet != NULL)
+                *sizeRet = size;
+        }
+    }
+    fclose(file);
+
+    return(data);
+}
+
diff --git a/fuzz/fuzz.h b/fuzz/fuzz.h
index 1cb788f5c..c39fa65e6 100644
--- a/fuzz/fuzz.h
+++ b/fuzz/fuzz.h
@@ -8,6 +8,7 @@
 #define __XML_FUZZERCOMMON_H__
 
 #include <stddef.h>
+#include <stdio.h>
 #include <libxml/parser.h>
 
 #ifdef __cplusplus
@@ -61,6 +62,9 @@ size_t
 xmlFuzzExtractStrings(const char *data, size_t size, char **strings,
                       size_t numStrings);
 
+char *
+xmlSlurpFile(const char *path, size_t *size);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/fuzz/testFuzzer.c b/fuzz/testFuzzer.c
index f6be7b8fe..678f3243d 100644
--- a/fuzz/testFuzzer.c
+++ b/fuzz/testFuzzer.c
@@ -6,13 +6,93 @@
  */
 
 #include <string.h>
+#include <glob.h>
 #include <libxml/parser.h>
 #include <libxml/tree.h>
 #include <libxml/xmlstring.h>
 #include "fuzz.h"
 
-int
-main() {
+#define LLVMFuzzerInitialize fuzzHtmlInit
+#define LLVMFuzzerTestOneInput fuzzHtml
+#include "html.c"
+#undef LLVMFuzzerInitialize
+#undef LLVMFuzzerTestOneInput
+
+#define LLVMFuzzerInitialize fuzzRegexpInit
+#define LLVMFuzzerTestOneInput fuzzRegexp
+#include "regexp.c"
+#undef LLVMFuzzerInitialize
+#undef LLVMFuzzerTestOneInput
+
+#define LLVMFuzzerInitialize fuzzSchemaInit
+#define LLVMFuzzerTestOneInput fuzzSchema
+#include "schema.c"
+#undef LLVMFuzzerInitialize
+#undef LLVMFuzzerTestOneInput
+
+#define LLVMFuzzerInitialize fuzzUriInit
+#define LLVMFuzzerTestOneInput fuzzUri
+#include "uri.c"
+#undef LLVMFuzzerInitialize
+#undef LLVMFuzzerTestOneInput
+
+#define LLVMFuzzerInitialize fuzzXmlInit
+#define LLVMFuzzerTestOneInput fuzzXml
+#include "xml.c"
+#undef LLVMFuzzerInitialize
+#undef LLVMFuzzerTestOneInput
+
+#define LLVMFuzzerInitialize fuzzXPathInit
+#define LLVMFuzzerTestOneInput fuzzXPath
+#include "xpath.c"
+#undef LLVMFuzzerInitialize
+#undef LLVMFuzzerTestOneInput
+
+typedef int
+(*initFunc)(int *argc, char ***argv);
+typedef int
+(*fuzzFunc)(const char *data, size_t size);
+
+int numInputs;
+
+static int
+testFuzzer(initFunc init, fuzzFunc fuzz, const char *pattern) {
+    glob_t globbuf;
+    int ret = -1;
+    int i;
+
+    if (glob(pattern, 0, NULL, &globbuf) != 0) {
+        fprintf(stderr, "pattern %s matches no files\n", pattern);
+        return(-1);
+    }
+
+    if (init != NULL)
+        init(NULL, NULL);
+
+    for (i = 0; i < globbuf.gl_pathc; i++) {
+        const char *path = globbuf.gl_pathv[i];
+        char *data;
+        size_t size;
+
+        data = xmlSlurpFile(path, &size);
+        if (data == NULL) {
+            fprintf(stderr, "couldn't read %s\n", path);
+            goto error;
+        }
+        fuzz(data, size);
+        xmlFree(data);
+
+        numInputs++;
+    }
+
+    ret = 0;
+error:
+    globfree(&globbuf);
+    return(ret);
+}
+
+static int
+testEntityLoader() {
     static const char data[] =
         "doc.xml\\\n"
         "<!DOCTYPE doc SYSTEM \"doc.dtd\">\n"
@@ -53,3 +133,28 @@ main() {
     return(ret);
 }
 
+int
+main() {
+    int ret = 0;
+
+    if (testEntityLoader() != 0)
+        ret = 1;
+    if (testFuzzer(fuzzHtmlInit, fuzzHtml, "seed/html/*") != 0)
+        ret = 1;
+    if (testFuzzer(fuzzRegexpInit, fuzzRegexp, "seed/regexp/*") != 0)
+        ret = 1;
+    if (testFuzzer(fuzzSchemaInit, fuzzSchema, "seed/schema/*") != 0)
+        ret = 1;
+    if (testFuzzer(NULL, fuzzUri, "seed/uri/*") != 0)
+        ret = 1;
+    if (testFuzzer(fuzzXmlInit, fuzzXml, "seed/xml/*") != 0)
+        ret = 1;
+    if (testFuzzer(fuzzXPathInit, fuzzXPath, "seed/xpath/*") != 0)
+        ret = 1;
+
+    if (ret == 0)
+        printf("Successfully tested %d inputs\n", numInputs);
+
+    return(ret);
+}
+
diff --git a/fuzz/xpathSeed.c b/fuzz/xpathSeed.c
index 2f6b59110..1d2c8a4dc 100644
--- a/fuzz/xpathSeed.c
+++ b/fuzz/xpathSeed.c
@@ -52,27 +52,12 @@ main(int argc, char **argv) {
 
     for (i = 0; i < globbuf.gl_pathc; i++) {
         char *path = globbuf.gl_pathv[i];
-        FILE *xmlFile;
-        struct stat statbuf;
 
-        if ((stat(path, &statbuf) != 0) || (!S_ISREG(statbuf.st_mode)))
-            continue;
-        size = statbuf.st_size;
-        xmlFile = fopen(path, "rb");
-        if (xmlFile == NULL) {
-            ret = 1;
-            continue;
-        }
-        xml.data = xmlMalloc(size + 1);
+        xml.data = xmlSlurpFile(path, NULL);
         if (xml.data == NULL) {
             ret = 1;
-            goto close;
-        }
-        if (fread(xml.data, 1, size, xmlFile) != size) {
-            ret = 1;
-            goto free;
+            continue;
         }
-        xml.data[size] = 0;
         xml.name = basename(path);
         xml.prefix = xml.name;
         xml.counter = 1;
@@ -82,10 +67,7 @@ main(int argc, char **argv) {
         if (processXml(argv[1], &xml, "xptr", 1) != 0)
             ret = 1;
 
-free:
         xmlFree(xml.data);
-close:
-        fclose(xmlFile);
     }
 
     globfree(&globbuf);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]