Edit

kc3-lang/libxml2/fuzz/schema.c

Branch :

  • Show log

    Commit

  • Author : Nick Wellnhofer
    Date : 2024-12-11 16:24:23
    Hash : c6c6d8af
    Message : fuzz: Mutate fuzz data chunks separately Implement a custom mutator that takes a list of fixed-size chunks which are mutated with a given probability. This makes sure that values like parser options or failure position are mutated regularly even as the fuzz data grows large. Values can also be adjusted temporarily to make the fuzzer focus on failure injection, for example. Thanks to David Kilzer for the idea.

  • fuzz/schema.c
  • /*
     * schema.c: a libFuzzer target to test the XML Schema processor.
     *
     * See Copyright for the status of this software.
     */
    
    #ifndef XML_DEPRECATED
      #define XML_DEPRECATED
    #endif
    
    #include <libxml/catalog.h>
    #include <libxml/xmlschemas.h>
    #include <libxml/xmlschemastypes.h>
    #include "fuzz.h"
    
    int
    LLVMFuzzerInitialize(int *argc ATTRIBUTE_UNUSED,
                         char ***argv ATTRIBUTE_UNUSED) {
        xmlFuzzMemSetup();
        xmlInitParser();
    #ifdef LIBXML_CATALOG_ENABLED
        xmlInitializeCatalog();
        xmlCatalogSetDefaults(XML_CATA_ALLOW_NONE);
    #endif
    
        return 0;
    }
    
    int
    LLVMFuzzerTestOneInput(const char *data, size_t size) {
        xmlSchemaParserCtxtPtr pctxt;
        xmlSchemaPtr schema;
        size_t failurePos;
    
        if (size > 200000)
            return(0);
    
        xmlFuzzDataInit(data, size);
    
        failurePos = xmlFuzzReadInt(4) % (size + 100);
    
        xmlFuzzReadEntities();
    
        xmlFuzzInjectFailure(failurePos);
        pctxt = xmlSchemaNewParserCtxt(xmlFuzzMainUrl());
        xmlSchemaSetParserStructuredErrors(pctxt, xmlFuzzSErrorFunc, NULL);
        xmlSchemaSetResourceLoader(pctxt, xmlFuzzResourceLoader, NULL);
        schema = xmlSchemaParse(pctxt);
        xmlSchemaFreeParserCtxt(pctxt);
    
        if (schema != NULL) {
            xmlSchemaValidCtxtPtr vctxt;
            xmlParserCtxtPtr ctxt;
            xmlDocPtr doc;
    
            ctxt = xmlNewParserCtxt();
            xmlCtxtSetErrorHandler(ctxt, xmlFuzzSErrorFunc, NULL);
            xmlCtxtSetResourceLoader(ctxt, xmlFuzzResourceLoader, NULL);
            doc = xmlCtxtReadFile(ctxt, xmlFuzzSecondaryUrl(), NULL,
                                  XML_PARSE_NOENT);
            xmlFreeParserCtxt(ctxt);
    
            vctxt = xmlSchemaNewValidCtxt(schema);
            xmlSchemaSetValidStructuredErrors(vctxt, xmlFuzzSErrorFunc, NULL);
            xmlSchemaValidateDoc(vctxt, doc);
            xmlSchemaFreeValidCtxt(vctxt);
    
            xmlFreeDoc(doc);
            xmlSchemaFree(schema);
        }
    
        xmlFuzzInjectFailure(0);
        xmlFuzzDataCleanup();
        xmlResetLastError();
        xmlSchemaCleanupTypes();
    
        return(0);
    }
    
    size_t
    LLVMFuzzerCustomMutator(char *data, size_t size, size_t maxSize,
                            unsigned seed) {
        static const xmlFuzzChunkDesc chunks[] = {
            { 4, XML_FUZZ_PROB_ONE / 10 }, /* failurePos */
            { 0, 0 }
        };
    
        return xmlFuzzMutateChunks(chunks, data, size, maxSize, seed,
                                   LLVMFuzzerMutate);
    }