mirror of
				https://gitlab.gnome.org/GNOME/libxml2.git
				synced 2025-10-27 12:15:34 +03:00 
			
		
		
		
	
		
			
				
	
	
		
			201 lines
		
	
	
		
			4.8 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			201 lines
		
	
	
		
			4.8 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /*
 | |
|  * testFuzzer.c: Test program for the custom entity loader used to fuzz
 | |
|  * with multiple inputs.
 | |
|  *
 | |
|  * See Copyright for the status of this software.
 | |
|  */
 | |
| 
 | |
| #include <string.h>
 | |
| #include <glob.h>
 | |
| #include <libxml/parser.h>
 | |
| #include <libxml/tree.h>
 | |
| #include <libxml/xmlstring.h>
 | |
| #include "fuzz.h"
 | |
| 
 | |
| #ifdef HAVE_HTML_FUZZER
 | |
| int fuzzHtmlInit(int *argc, char ***argv);
 | |
| int fuzzHtml(const char *data, size_t size);
 | |
| #define LLVMFuzzerInitialize fuzzHtmlInit
 | |
| #define LLVMFuzzerTestOneInput fuzzHtml
 | |
| #include "html.c"
 | |
| #undef LLVMFuzzerInitialize
 | |
| #undef LLVMFuzzerTestOneInput
 | |
| #endif
 | |
| 
 | |
| #ifdef HAVE_REGEXP_FUZZER
 | |
| int fuzzRegexpInit(int *argc, char ***argv);
 | |
| int fuzzRegexp(const char *data, size_t size);
 | |
| #define LLVMFuzzerInitialize fuzzRegexpInit
 | |
| #define LLVMFuzzerTestOneInput fuzzRegexp
 | |
| #include "regexp.c"
 | |
| #undef LLVMFuzzerInitialize
 | |
| #undef LLVMFuzzerTestOneInput
 | |
| #endif
 | |
| 
 | |
| #ifdef HAVE_SCHEMA_FUZZER
 | |
| int fuzzSchemaInit(int *argc, char ***argv);
 | |
| int fuzzSchema(const char *data, size_t size);
 | |
| #define LLVMFuzzerInitialize fuzzSchemaInit
 | |
| #define LLVMFuzzerTestOneInput fuzzSchema
 | |
| #include "schema.c"
 | |
| #undef LLVMFuzzerInitialize
 | |
| #undef LLVMFuzzerTestOneInput
 | |
| #endif
 | |
| 
 | |
| #ifdef HAVE_URI_FUZZER
 | |
| int fuzzUriInit(int *argc, char ***argv);
 | |
| int fuzzUri(const char *data, size_t size);
 | |
| #define LLVMFuzzerInitialize fuzzUriInit
 | |
| #define LLVMFuzzerTestOneInput fuzzUri
 | |
| #include "uri.c"
 | |
| #undef LLVMFuzzerInitialize
 | |
| #undef LLVMFuzzerTestOneInput
 | |
| #endif
 | |
| 
 | |
| #ifdef HAVE_XML_FUZZER
 | |
| int fuzzXmlInit(int *argc, char ***argv);
 | |
| int fuzzXml(const char *data, size_t size);
 | |
| #define LLVMFuzzerInitialize fuzzXmlInit
 | |
| #define LLVMFuzzerTestOneInput fuzzXml
 | |
| #include "xml.c"
 | |
| #undef LLVMFuzzerInitialize
 | |
| #undef LLVMFuzzerTestOneInput
 | |
| #endif
 | |
| 
 | |
| #ifdef HAVE_XPATH_FUZZER
 | |
| int fuzzXPathInit(int *argc, char ***argv);
 | |
| int fuzzXPath(const char *data, size_t size);
 | |
| #define LLVMFuzzerInitialize fuzzXPathInit
 | |
| #define LLVMFuzzerTestOneInput fuzzXPath
 | |
| #include "xpath.c"
 | |
| #undef LLVMFuzzerInitialize
 | |
| #undef LLVMFuzzerTestOneInput
 | |
| #endif
 | |
| 
 | |
| 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;
 | |
|     size_t 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);
 | |
| }
 | |
| 
 | |
| #ifdef HAVE_XML_FUZZER
 | |
| static int
 | |
| testEntityLoader(void) {
 | |
|     static const char data[] =
 | |
|         "doc.xml\\\n"
 | |
|         "<!DOCTYPE doc SYSTEM \"doc.dtd\">\n"
 | |
|         "<doc>&ent;</doc>\\\n"
 | |
|         "doc.dtd\\\n"
 | |
|         "<!ELEMENT doc (#PCDATA)>\n"
 | |
|         "<!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);
 | |
| 
 | |
|     xmlFuzzDataInit(data, sizeof(data) - 1);
 | |
|     xmlFuzzReadEntities();
 | |
|     docBuffer = xmlFuzzMainEntity(&docSize);
 | |
|     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;
 | |
|     }
 | |
| 
 | |
|     xmlFree(out);
 | |
|     xmlFreeDoc(doc);
 | |
|     xmlFuzzDataCleanup();
 | |
| 
 | |
|     return(ret);
 | |
| }
 | |
| #endif
 | |
| 
 | |
| int
 | |
| main(void) {
 | |
|     int ret = 0;
 | |
| 
 | |
| #ifdef HAVE_XML_FUZZER
 | |
|     if (testEntityLoader() != 0)
 | |
|         ret = 1;
 | |
| #endif
 | |
| #ifdef HAVE_HTML_FUZZER
 | |
|     if (testFuzzer(fuzzHtmlInit, fuzzHtml, "seed/html/*") != 0)
 | |
|         ret = 1;
 | |
| #endif
 | |
| #ifdef HAVE_REGEXP_FUZZER
 | |
|     if (testFuzzer(fuzzRegexpInit, fuzzRegexp, "seed/regexp/*") != 0)
 | |
|         ret = 1;
 | |
| #endif
 | |
| #ifdef HAVE_SCHEMA_FUZZER
 | |
|     if (testFuzzer(fuzzSchemaInit, fuzzSchema, "seed/schema/*") != 0)
 | |
|         ret = 1;
 | |
| #endif
 | |
| #ifdef HAVE_URI_FUZZER
 | |
|     if (testFuzzer(NULL, fuzzUri, "seed/uri/*") != 0)
 | |
|         ret = 1;
 | |
| #endif
 | |
| #ifdef HAVE_XML_FUZZER
 | |
|     if (testFuzzer(fuzzXmlInit, fuzzXml, "seed/xml/*") != 0)
 | |
|         ret = 1;
 | |
| #endif
 | |
| #ifdef HAVE_XPATH_FUZZER
 | |
|     if (testFuzzer(fuzzXPathInit, fuzzXPath, "seed/xpath/*") != 0)
 | |
|         ret = 1;
 | |
| #endif
 | |
| 
 | |
|     if (ret == 0)
 | |
|         printf("Successfully tested %d inputs\n", numInputs);
 | |
| 
 | |
|     return(ret);
 | |
| }
 | |
| 
 |