(root)/
libxml2-2.12.3/
fuzz/
testFuzzer.c
       1  /*
       2   * testFuzzer.c: Test program for the custom entity loader used to fuzz
       3   * with multiple inputs.
       4   *
       5   * See Copyright for the status of this software.
       6   */
       7  
       8  #include <string.h>
       9  #include <glob.h>
      10  #include <libxml/parser.h>
      11  #include <libxml/tree.h>
      12  #include <libxml/xmlstring.h>
      13  #include "fuzz.h"
      14  
      15  #ifdef HAVE_HTML_FUZZER
      16  int fuzzHtmlInit(int *argc, char ***argv);
      17  int fuzzHtml(const char *data, size_t size);
      18  #define LLVMFuzzerInitialize fuzzHtmlInit
      19  #define LLVMFuzzerTestOneInput fuzzHtml
      20  #include "html.c"
      21  #undef LLVMFuzzerInitialize
      22  #undef LLVMFuzzerTestOneInput
      23  #endif
      24  
      25  #ifdef HAVE_REGEXP_FUZZER
      26  int fuzzRegexpInit(int *argc, char ***argv);
      27  int fuzzRegexp(const char *data, size_t size);
      28  #define LLVMFuzzerInitialize fuzzRegexpInit
      29  #define LLVMFuzzerTestOneInput fuzzRegexp
      30  #include "regexp.c"
      31  #undef LLVMFuzzerInitialize
      32  #undef LLVMFuzzerTestOneInput
      33  #endif
      34  
      35  #ifdef HAVE_SCHEMA_FUZZER
      36  int fuzzSchemaInit(int *argc, char ***argv);
      37  int fuzzSchema(const char *data, size_t size);
      38  #define LLVMFuzzerInitialize fuzzSchemaInit
      39  #define LLVMFuzzerTestOneInput fuzzSchema
      40  #include "schema.c"
      41  #undef LLVMFuzzerInitialize
      42  #undef LLVMFuzzerTestOneInput
      43  #endif
      44  
      45  #ifdef HAVE_URI_FUZZER
      46  int fuzzUriInit(int *argc, char ***argv);
      47  int fuzzUri(const char *data, size_t size);
      48  #define LLVMFuzzerInitialize fuzzUriInit
      49  #define LLVMFuzzerTestOneInput fuzzUri
      50  #include "uri.c"
      51  #undef LLVMFuzzerInitialize
      52  #undef LLVMFuzzerTestOneInput
      53  #endif
      54  
      55  #ifdef HAVE_VALID_FUZZER
      56  int fuzzValidInit(int *argc, char ***argv);
      57  int fuzzValid(const char *data, size_t size);
      58  #define LLVMFuzzerInitialize fuzzValidInit
      59  #define LLVMFuzzerTestOneInput fuzzValid
      60  #include "valid.c"
      61  #undef LLVMFuzzerInitialize
      62  #undef LLVMFuzzerTestOneInput
      63  #endif
      64  
      65  #ifdef HAVE_XINCLUDE_FUZZER
      66  int fuzzXIncludeInit(int *argc, char ***argv);
      67  int fuzzXInclude(const char *data, size_t size);
      68  #define LLVMFuzzerInitialize fuzzXIncludeInit
      69  #define LLVMFuzzerTestOneInput fuzzXInclude
      70  #include "xinclude.c"
      71  #undef LLVMFuzzerInitialize
      72  #undef LLVMFuzzerTestOneInput
      73  #endif
      74  
      75  #ifdef HAVE_XML_FUZZER
      76  int fuzzXmlInit(int *argc, char ***argv);
      77  int fuzzXml(const char *data, size_t size);
      78  #define LLVMFuzzerInitialize fuzzXmlInit
      79  #define LLVMFuzzerTestOneInput fuzzXml
      80  #include "xml.c"
      81  #undef LLVMFuzzerInitialize
      82  #undef LLVMFuzzerTestOneInput
      83  #endif
      84  
      85  #ifdef HAVE_XPATH_FUZZER
      86  int fuzzXPathInit(int *argc, char ***argv);
      87  int fuzzXPath(const char *data, size_t size);
      88  #define LLVMFuzzerInitialize fuzzXPathInit
      89  #define LLVMFuzzerTestOneInput fuzzXPath
      90  #include "xpath.c"
      91  #undef LLVMFuzzerInitialize
      92  #undef LLVMFuzzerTestOneInput
      93  #endif
      94  
      95  typedef int
      96  (*initFunc)(int *argc, char ***argv);
      97  typedef int
      98  (*fuzzFunc)(const char *data, size_t size);
      99  
     100  int numInputs;
     101  
     102  static int
     103  testFuzzer(initFunc init, fuzzFunc fuzz, const char *pattern) {
     104      glob_t globbuf;
     105      int ret = -1;
     106      size_t i;
     107  
     108      if (glob(pattern, 0, NULL, &globbuf) != 0) {
     109          fprintf(stderr, "pattern %s matches no files\n", pattern);
     110          return(-1);
     111      }
     112  
     113      if (init != NULL)
     114          init(NULL, NULL);
     115  
     116      for (i = 0; i < globbuf.gl_pathc; i++) {
     117          const char *path = globbuf.gl_pathv[i];
     118          char *data;
     119          size_t size;
     120  
     121          data = xmlSlurpFile(path, &size);
     122          if (data == NULL) {
     123              fprintf(stderr, "couldn't read %s\n", path);
     124              goto error;
     125          }
     126          fuzz(data, size);
     127          xmlFree(data);
     128  
     129          numInputs++;
     130      }
     131  
     132      ret = 0;
     133  error:
     134      globfree(&globbuf);
     135      return(ret);
     136  }
     137  
     138  #ifdef HAVE_XML_FUZZER
     139  static int
     140  testEntityLoader(void) {
     141      static const char data[] =
     142          "doc.xml\\\n"
     143          "<!DOCTYPE doc SYSTEM \"doc.dtd\">\n"
     144          "<doc>&ent;</doc>\\\n"
     145          "doc.dtd\\\n"
     146          "<!ELEMENT doc (#PCDATA)>\n"
     147          "<!ENTITY ent SYSTEM \"ent.txt\">\\\n"
     148          "ent.txt\\\n"
     149          "Hello, world!\\\n";
     150      const char *docBuffer;
     151      size_t docSize;
     152      xmlDocPtr doc;
     153      int ret = 0;
     154  
     155      xmlSetExternalEntityLoader(xmlFuzzEntityLoader);
     156  
     157      xmlFuzzDataInit(data, sizeof(data) - 1);
     158      xmlFuzzReadEntities();
     159      docBuffer = xmlFuzzMainEntity(&docSize);
     160      doc = xmlReadMemory(docBuffer, docSize, NULL, NULL,
     161                          XML_PARSE_NOENT | XML_PARSE_DTDLOAD);
     162  
     163  #ifdef LIBXML_OUTPUT_ENABLED
     164      {
     165          static xmlChar expected[] =
     166              "<?xml version=\"1.0\"?>\n"
     167              "<!DOCTYPE doc SYSTEM \"doc.dtd\">\n"
     168              "<doc>Hello, world!</doc>\n";
     169          xmlChar *out;
     170  
     171          xmlDocDumpMemory(doc, &out, NULL);
     172          if (xmlStrcmp(out, expected) != 0) {
     173              fprintf(stderr, "Expected:\n%sGot:\n%s", expected, out);
     174              ret = 1;
     175          }
     176          xmlFree(out);
     177      }
     178  #endif
     179  
     180      xmlFreeDoc(doc);
     181      xmlFuzzDataCleanup();
     182  
     183      return(ret);
     184  }
     185  #endif
     186  
     187  int
     188  main(void) {
     189      int ret = 0;
     190  
     191  #ifdef HAVE_XML_FUZZER
     192      if (testEntityLoader() != 0)
     193          ret = 1;
     194  #endif
     195  #ifdef HAVE_HTML_FUZZER
     196      if (testFuzzer(fuzzHtmlInit, fuzzHtml, "seed/html/*") != 0)
     197          ret = 1;
     198  #endif
     199  #ifdef HAVE_REGEXP_FUZZER
     200      if (testFuzzer(fuzzRegexpInit, fuzzRegexp, "seed/regexp/*") != 0)
     201          ret = 1;
     202  #endif
     203  #ifdef HAVE_SCHEMA_FUZZER
     204      if (testFuzzer(fuzzSchemaInit, fuzzSchema, "seed/schema/*") != 0)
     205          ret = 1;
     206  #endif
     207  #ifdef HAVE_URI_FUZZER
     208      if (testFuzzer(fuzzUriInit, fuzzUri, "seed/uri/*") != 0)
     209          ret = 1;
     210  #endif
     211  #ifdef HAVE_VALID_FUZZER
     212      if (testFuzzer(fuzzValidInit, fuzzValid, "seed/valid/*") != 0)
     213          ret = 1;
     214  #endif
     215  #ifdef HAVE_XINCLUDE_FUZZER
     216      if (testFuzzer(fuzzXIncludeInit, fuzzXInclude, "seed/xinclude/*") != 0)
     217          ret = 1;
     218  #endif
     219  #ifdef HAVE_XML_FUZZER
     220      if (testFuzzer(fuzzXmlInit, fuzzXml, "seed/xml/*") != 0)
     221          ret = 1;
     222  #endif
     223  #ifdef HAVE_XPATH_FUZZER
     224      if (testFuzzer(fuzzXPathInit, fuzzXPath, "seed/xpath/*") != 0)
     225          ret = 1;
     226  #endif
     227  
     228      if (ret == 0)
     229          printf("Successfully tested %d inputs\n", numInputs);
     230  
     231      return(ret);
     232  }
     233