Blame testlimits.c

Packit Service a31ea6
/*
Packit Service a31ea6
 * testlimits.c: C program to run libxml2 regression tests checking various
Packit Service a31ea6
 *       limits in document size. Will consume a lot of RAM and CPU cycles
Packit Service a31ea6
 *
Packit Service a31ea6
 * To compile on Unixes:
Packit Service a31ea6
 * cc -o testlimits `xml2-config --cflags` testlimits.c `xml2-config --libs` -lpthread
Packit Service a31ea6
 *
Packit Service a31ea6
 * See Copyright for the status of this software.
Packit Service a31ea6
 *
Packit Service a31ea6
 * daniel@veillard.com
Packit Service a31ea6
 */
Packit Service a31ea6
Packit Service a31ea6
#include "libxml.h"
Packit Service a31ea6
#include <stdio.h>
Packit Service a31ea6
Packit Service a31ea6
#if !defined(_WIN32) || defined(__CYGWIN__)
Packit Service a31ea6
#include <unistd.h>
Packit Service a31ea6
#endif
Packit Service a31ea6
#include <string.h>
Packit Service a31ea6
#include <sys/types.h>
Packit Service a31ea6
#include <sys/stat.h>
Packit Service a31ea6
#include <fcntl.h>
Packit Service a31ea6
#include <time.h>
Packit Service a31ea6
Packit Service a31ea6
#include <libxml/parser.h>
Packit Service a31ea6
#include <libxml/parserInternals.h>
Packit Service a31ea6
#include <libxml/tree.h>
Packit Service a31ea6
#include <libxml/uri.h>
Packit Service a31ea6
#ifdef LIBXML_READER_ENABLED
Packit Service a31ea6
#include <libxml/xmlreader.h>
Packit Service a31ea6
#endif
Packit Service a31ea6
Packit Service a31ea6
static int verbose = 0;
Packit Service a31ea6
static int tests_quiet = 0;
Packit Service a31ea6
Packit Service a31ea6
/************************************************************************
Packit Service a31ea6
 *									*
Packit Service a31ea6
 *		time handling                                           *
Packit Service a31ea6
 *									*
Packit Service a31ea6
 ************************************************************************/
Packit Service a31ea6
Packit Service a31ea6
/* maximum time for one parsing before declaring a timeout */
Packit Service a31ea6
#define MAX_TIME 2 /* seconds */
Packit Service a31ea6
Packit Service a31ea6
static clock_t t0;
Packit Service a31ea6
int timeout = 0;
Packit Service a31ea6
Packit Service a31ea6
static void reset_timout(void) {
Packit Service a31ea6
    timeout = 0;
Packit Service a31ea6
    t0 = clock();
Packit Service a31ea6
}
Packit Service a31ea6
Packit Service a31ea6
static int check_time(void) {
Packit Service a31ea6
    clock_t tnow = clock();
Packit Service a31ea6
    if (((tnow - t0) / CLOCKS_PER_SEC) > MAX_TIME) {
Packit Service a31ea6
        timeout = 1;
Packit Service a31ea6
        return(0);
Packit Service a31ea6
    }
Packit Service a31ea6
    return(1);
Packit Service a31ea6
}
Packit Service a31ea6
Packit Service a31ea6
/************************************************************************
Packit Service a31ea6
 *									*
Packit Service a31ea6
 *		Huge document generator					*
Packit Service a31ea6
 *									*
Packit Service a31ea6
 ************************************************************************/
Packit Service a31ea6
Packit Service a31ea6
#include <libxml/xmlIO.h>
Packit Service a31ea6
Packit Service a31ea6
/*
Packit Service a31ea6
 * Huge documents are built using fixed start and end chunks
Packit Service a31ea6
 * and filling between the two an unconventional amount of char data
Packit Service a31ea6
 */
Packit Service a31ea6
typedef struct hugeTest hugeTest;
Packit Service a31ea6
typedef hugeTest *hugeTestPtr;
Packit Service a31ea6
struct hugeTest {
Packit Service a31ea6
    const char *description;
Packit Service a31ea6
    const char *name;
Packit Service a31ea6
    const char *start;
Packit Service a31ea6
    const char *end;
Packit Service a31ea6
};
Packit Service a31ea6
Packit Service a31ea6
static struct hugeTest hugeTests[] = {
Packit Service a31ea6
    { "Huge text node", "huge:textNode", "<foo>", "</foo>" },
Packit Service a31ea6
    { "Huge attribute node", "huge:attrNode", "<foo bar='", "'/>" },
Packit Service a31ea6
    { "Huge comment node", "huge:commentNode", "<foo></foo>" },
Packit Service a31ea6
    { "Huge PI node", "huge:piNode", "<foo></foo>" },
Packit Service a31ea6
};
Packit Service a31ea6
Packit Service a31ea6
static const char *current;
Packit Service a31ea6
static int rlen;
Packit Service a31ea6
static unsigned int currentTest = 0;
Packit Service a31ea6
static int instate = 0;
Packit Service a31ea6
Packit Service a31ea6
/**
Packit Service a31ea6
 * hugeMatch:
Packit Service a31ea6
 * @URI: an URI to test
Packit Service a31ea6
 *
Packit Service a31ea6
 * Check for an huge: query
Packit Service a31ea6
 *
Packit Service a31ea6
 * Returns 1 if yes and 0 if another Input module should be used
Packit Service a31ea6
 */
Packit Service a31ea6
static int
Packit Service a31ea6
hugeMatch(const char * URI) {
Packit Service a31ea6
    if ((URI != NULL) && (!strncmp(URI, "huge:", 5)))
Packit Service a31ea6
        return(1);
Packit Service a31ea6
    return(0);
Packit Service a31ea6
}
Packit Service a31ea6
Packit Service a31ea6
/**
Packit Service a31ea6
 * hugeOpen:
Packit Service a31ea6
 * @URI: an URI to test
Packit Service a31ea6
 *
Packit Service a31ea6
 * Return a pointer to the huge: query handler, in this example simply
Packit Service a31ea6
 * the current pointer...
Packit Service a31ea6
 *
Packit Service a31ea6
 * Returns an Input context or NULL in case or error
Packit Service a31ea6
 */
Packit Service a31ea6
static void *
Packit Service a31ea6
hugeOpen(const char * URI) {
Packit Service a31ea6
    if ((URI == NULL) || (strncmp(URI, "huge:", 5)))
Packit Service a31ea6
        return(NULL);
Packit Service a31ea6
Packit Service a31ea6
    for (currentTest = 0;currentTest < sizeof(hugeTests)/sizeof(hugeTests[0]);
Packit Service a31ea6
         currentTest++)
Packit Service a31ea6
         if (!strcmp(hugeTests[currentTest].name, URI))
Packit Service a31ea6
             goto found;
Packit Service a31ea6
Packit Service a31ea6
    return(NULL);
Packit Service a31ea6
Packit Service a31ea6
found:
Packit Service a31ea6
    rlen = strlen(hugeTests[currentTest].start);
Packit Service a31ea6
    current = hugeTests[currentTest].start;
Packit Service a31ea6
    instate = 0;
Packit Service a31ea6
    return((void *) current);
Packit Service a31ea6
}
Packit Service a31ea6
Packit Service a31ea6
/**
Packit Service a31ea6
 * hugeClose:
Packit Service a31ea6
 * @context: the read context
Packit Service a31ea6
 *
Packit Service a31ea6
 * Close the huge: query handler
Packit Service a31ea6
 *
Packit Service a31ea6
 * Returns 0 or -1 in case of error
Packit Service a31ea6
 */
Packit Service a31ea6
static int
Packit Service a31ea6
hugeClose(void * context) {
Packit Service a31ea6
    if (context == NULL) return(-1);
Packit Service a31ea6
    fprintf(stderr, "\n");
Packit Service a31ea6
    return(0);
Packit Service a31ea6
}
Packit Service a31ea6
Packit Service a31ea6
#define CHUNK 4096
Packit Service a31ea6
Packit Service a31ea6
char filling[CHUNK + 1];
Packit Service a31ea6
Packit Service a31ea6
static void fillFilling(void) {
Packit Service a31ea6
    int i;
Packit Service a31ea6
Packit Service a31ea6
    for (i = 0;i < CHUNK;i++) {
Packit Service a31ea6
        filling[i] = 'a';
Packit Service a31ea6
    }
Packit Service a31ea6
    filling[CHUNK] = 0;
Packit Service a31ea6
}
Packit Service a31ea6
Packit Service a31ea6
size_t maxlen = 64 * 1024 * 1024;
Packit Service a31ea6
size_t curlen = 0;
Packit Service a31ea6
size_t dotlen;
Packit Service a31ea6
Packit Service a31ea6
/**
Packit Service a31ea6
 * hugeRead:
Packit Service a31ea6
 * @context: the read context
Packit Service a31ea6
 * @buffer: where to store data
Packit Service a31ea6
 * @len: number of bytes to read
Packit Service a31ea6
 *
Packit Service a31ea6
 * Implement an huge: query read.
Packit Service a31ea6
 *
Packit Service a31ea6
 * Returns the number of bytes read or -1 in case of error
Packit Service a31ea6
 */
Packit Service a31ea6
static int
Packit Service a31ea6
hugeRead(void *context, char *buffer, int len)
Packit Service a31ea6
{
Packit Service a31ea6
    if ((context == NULL) || (buffer == NULL) || (len < 0))
Packit Service a31ea6
        return (-1);
Packit Service a31ea6
Packit Service a31ea6
    if (instate == 0) {
Packit Service a31ea6
        if (len >= rlen) {
Packit Service a31ea6
            len = rlen;
Packit Service a31ea6
            rlen = 0;
Packit Service a31ea6
            memcpy(buffer, current, len);
Packit Service a31ea6
            instate = 1;
Packit Service a31ea6
            curlen = 0;
Packit Service a31ea6
            dotlen = maxlen / 10;
Packit Service a31ea6
        } else {
Packit Service a31ea6
            memcpy(buffer, current, len);
Packit Service a31ea6
            rlen -= len;
Packit Service a31ea6
            current += len;
Packit Service a31ea6
        }
Packit Service a31ea6
    } else if (instate == 2) {
Packit Service a31ea6
        if (len >= rlen) {
Packit Service a31ea6
            len = rlen;
Packit Service a31ea6
            rlen = 0;
Packit Service a31ea6
            memcpy(buffer, current, len);
Packit Service a31ea6
            instate = 3;
Packit Service a31ea6
            curlen = 0;
Packit Service a31ea6
        } else {
Packit Service a31ea6
            memcpy(buffer, current, len);
Packit Service a31ea6
            rlen -= len;
Packit Service a31ea6
            current += len;
Packit Service a31ea6
        }
Packit Service a31ea6
    } else if (instate == 1) {
Packit Service a31ea6
        if (len > CHUNK) len = CHUNK;
Packit Service a31ea6
        memcpy(buffer, &filling[0], len);
Packit Service a31ea6
        curlen += len;
Packit Service a31ea6
        if (curlen >= maxlen) {
Packit Service a31ea6
            rlen = strlen(hugeTests[currentTest].end);
Packit Service a31ea6
            current = hugeTests[currentTest].end;
Packit Service a31ea6
            instate = 2;
Packit Service a31ea6
	} else {
Packit Service a31ea6
            if (curlen > dotlen) {
Packit Service a31ea6
                fprintf(stderr, ".");
Packit Service a31ea6
                dotlen += maxlen / 10;
Packit Service a31ea6
            }
Packit Service a31ea6
        }
Packit Service a31ea6
    } else
Packit Service a31ea6
      len = 0;
Packit Service a31ea6
    return (len);
Packit Service a31ea6
}
Packit Service a31ea6
Packit Service a31ea6
/************************************************************************
Packit Service a31ea6
 *									*
Packit Service a31ea6
 *		Crazy document generator				*
Packit Service a31ea6
 *									*
Packit Service a31ea6
 ************************************************************************/
Packit Service a31ea6
Packit Service a31ea6
unsigned int crazy_indx = 0;
Packit Service a31ea6
Packit Service a31ea6
const char *crazy = "\
Packit Service a31ea6
\
Packit Service a31ea6
\
Packit Service a31ea6
Packit Service a31ea6
\
Packit Service a31ea6
\
Packit Service a31ea6
\
Packit Service a31ea6
\
Packit Service a31ea6
]>\
Packit Service a31ea6
\
Packit Service a31ea6
\
Packit Service a31ea6
<foo bar='foo'>\
Packit Service a31ea6
\
Packit Service a31ea6
\
Packit Service a31ea6
foo\
Packit Service a31ea6
\
Packit Service a31ea6
</foo>\
Packit Service a31ea6
\
Packit Service a31ea6
";
Packit Service a31ea6
Packit Service a31ea6
/**
Packit Service a31ea6
 * crazyMatch:
Packit Service a31ea6
 * @URI: an URI to test
Packit Service a31ea6
 *
Packit Service a31ea6
 * Check for a crazy: query
Packit Service a31ea6
 *
Packit Service a31ea6
 * Returns 1 if yes and 0 if another Input module should be used
Packit Service a31ea6
 */
Packit Service a31ea6
static int
Packit Service a31ea6
crazyMatch(const char * URI) {
Packit Service a31ea6
    if ((URI != NULL) && (!strncmp(URI, "crazy:", 6)))
Packit Service a31ea6
        return(1);
Packit Service a31ea6
    return(0);
Packit Service a31ea6
}
Packit Service a31ea6
Packit Service a31ea6
/**
Packit Service a31ea6
 * crazyOpen:
Packit Service a31ea6
 * @URI: an URI to test
Packit Service a31ea6
 *
Packit Service a31ea6
 * Return a pointer to the crazy: query handler, in this example simply
Packit Service a31ea6
 * the current pointer...
Packit Service a31ea6
 *
Packit Service a31ea6
 * Returns an Input context or NULL in case or error
Packit Service a31ea6
 */
Packit Service a31ea6
static void *
Packit Service a31ea6
crazyOpen(const char * URI) {
Packit Service a31ea6
    if ((URI == NULL) || (strncmp(URI, "crazy:", 6)))
Packit Service a31ea6
        return(NULL);
Packit Service a31ea6
Packit Service a31ea6
    if (crazy_indx > strlen(crazy))
Packit Service a31ea6
        return(NULL);
Packit Service a31ea6
    reset_timout();
Packit Service a31ea6
    rlen = crazy_indx;
Packit Service a31ea6
    current = &crazy[0];
Packit Service a31ea6
    instate = 0;
Packit Service a31ea6
    return((void *) current);
Packit Service a31ea6
}
Packit Service a31ea6
Packit Service a31ea6
/**
Packit Service a31ea6
 * crazyClose:
Packit Service a31ea6
 * @context: the read context
Packit Service a31ea6
 *
Packit Service a31ea6
 * Close the crazy: query handler
Packit Service a31ea6
 *
Packit Service a31ea6
 * Returns 0 or -1 in case of error
Packit Service a31ea6
 */
Packit Service a31ea6
static int
Packit Service a31ea6
crazyClose(void * context) {
Packit Service a31ea6
    if (context == NULL) return(-1);
Packit Service a31ea6
    return(0);
Packit Service a31ea6
}
Packit Service a31ea6
Packit Service a31ea6
Packit Service a31ea6
/**
Packit Service a31ea6
 * crazyRead:
Packit Service a31ea6
 * @context: the read context
Packit Service a31ea6
 * @buffer: where to store data
Packit Service a31ea6
 * @len: number of bytes to read
Packit Service a31ea6
 *
Packit Service a31ea6
 * Implement an crazy: query read.
Packit Service a31ea6
 *
Packit Service a31ea6
 * Returns the number of bytes read or -1 in case of error
Packit Service a31ea6
 */
Packit Service a31ea6
static int
Packit Service a31ea6
crazyRead(void *context, char *buffer, int len)
Packit Service a31ea6
{
Packit Service a31ea6
    if ((context == NULL) || (buffer == NULL) || (len < 0))
Packit Service a31ea6
        return (-1);
Packit Service a31ea6
Packit Service a31ea6
    if ((check_time() <= 0) && (instate == 1)) {
Packit Service a31ea6
        fprintf(stderr, "\ntimeout in crazy(%d)\n", crazy_indx);
Packit Service a31ea6
        rlen = strlen(crazy) - crazy_indx;
Packit Service a31ea6
        current = &crazy[crazy_indx];
Packit Service a31ea6
        instate = 2;
Packit Service a31ea6
    }
Packit Service a31ea6
    if (instate == 0) {
Packit Service a31ea6
        if (len >= rlen) {
Packit Service a31ea6
            len = rlen;
Packit Service a31ea6
            rlen = 0;
Packit Service a31ea6
            memcpy(buffer, current, len);
Packit Service a31ea6
            instate = 1;
Packit Service a31ea6
            curlen = 0;
Packit Service a31ea6
        } else {
Packit Service a31ea6
            memcpy(buffer, current, len);
Packit Service a31ea6
            rlen -= len;
Packit Service a31ea6
            current += len;
Packit Service a31ea6
        }
Packit Service a31ea6
    } else if (instate == 2) {
Packit Service a31ea6
        if (len >= rlen) {
Packit Service a31ea6
            len = rlen;
Packit Service a31ea6
            rlen = 0;
Packit Service a31ea6
            memcpy(buffer, current, len);
Packit Service a31ea6
            instate = 3;
Packit Service a31ea6
            curlen = 0;
Packit Service a31ea6
        } else {
Packit Service a31ea6
            memcpy(buffer, current, len);
Packit Service a31ea6
            rlen -= len;
Packit Service a31ea6
            current += len;
Packit Service a31ea6
        }
Packit Service a31ea6
    } else if (instate == 1) {
Packit Service a31ea6
        if (len > CHUNK) len = CHUNK;
Packit Service a31ea6
        memcpy(buffer, &filling[0], len);
Packit Service a31ea6
        curlen += len;
Packit Service a31ea6
        if (curlen >= maxlen) {
Packit Service a31ea6
            rlen = strlen(crazy) - crazy_indx;
Packit Service a31ea6
            current = &crazy[crazy_indx];
Packit Service a31ea6
            instate = 2;
Packit Service a31ea6
        }
Packit Service a31ea6
    } else
Packit Service a31ea6
      len = 0;
Packit Service a31ea6
    return (len);
Packit Service a31ea6
}
Packit Service a31ea6
/************************************************************************
Packit Service a31ea6
 *									*
Packit Service a31ea6
 *		Libxml2 specific routines				*
Packit Service a31ea6
 *									*
Packit Service a31ea6
 ************************************************************************/
Packit Service a31ea6
Packit Service a31ea6
static int nb_tests = 0;
Packit Service a31ea6
static int nb_errors = 0;
Packit Service a31ea6
static int nb_leaks = 0;
Packit Service a31ea6
static int extraMemoryFromResolver = 0;
Packit Service a31ea6
Packit Service a31ea6
/*
Packit Service a31ea6
 * We need to trap calls to the resolver to not account memory for the catalog
Packit Service a31ea6
 * which is shared to the current running test. We also don't want to have
Packit Service a31ea6
 * network downloads modifying tests.
Packit Service a31ea6
 */
Packit Service a31ea6
static xmlParserInputPtr
Packit Service a31ea6
testExternalEntityLoader(const char *URL, const char *ID,
Packit Service a31ea6
			 xmlParserCtxtPtr ctxt) {
Packit Service a31ea6
    xmlParserInputPtr ret;
Packit Service a31ea6
    int memused = xmlMemUsed();
Packit Service a31ea6
Packit Service a31ea6
    ret = xmlNoNetExternalEntityLoader(URL, ID, ctxt);
Packit Service a31ea6
    extraMemoryFromResolver += xmlMemUsed() - memused;
Packit Service a31ea6
Packit Service a31ea6
    return(ret);
Packit Service a31ea6
}
Packit Service a31ea6
Packit Service a31ea6
/*
Packit Service a31ea6
 * Trapping the error messages at the generic level to grab the equivalent of
Packit Service a31ea6
 * stderr messages on CLI tools.
Packit Service a31ea6
 */
Packit Service a31ea6
static char testErrors[32769];
Packit Service a31ea6
static int testErrorsSize = 0;
Packit Service a31ea6
Packit Service a31ea6
static void XMLCDECL
Packit Service a31ea6
channel(void *ctx  ATTRIBUTE_UNUSED, const char *msg, ...) {
Packit Service a31ea6
    va_list args;
Packit Service a31ea6
    int res;
Packit Service a31ea6
Packit Service a31ea6
    if (testErrorsSize >= 32768)
Packit Service a31ea6
        return;
Packit Service a31ea6
    va_start(args, msg);
Packit Service a31ea6
    res = vsnprintf(&testErrors[testErrorsSize],
Packit Service a31ea6
                    32768 - testErrorsSize,
Packit Service a31ea6
		    msg, args);
Packit Service a31ea6
    va_end(args);
Packit Service a31ea6
    if (testErrorsSize + res >= 32768) {
Packit Service a31ea6
        /* buffer is full */
Packit Service a31ea6
	testErrorsSize = 32768;
Packit Service a31ea6
	testErrors[testErrorsSize] = 0;
Packit Service a31ea6
    } else {
Packit Service a31ea6
        testErrorsSize += res;
Packit Service a31ea6
    }
Packit Service a31ea6
    testErrors[testErrorsSize] = 0;
Packit Service a31ea6
}
Packit Service a31ea6
Packit Service a31ea6
/**
Packit Service a31ea6
 * xmlParserPrintFileContext:
Packit Service a31ea6
 * @input:  an xmlParserInputPtr input
Packit Service a31ea6
 *
Packit Service a31ea6
 * Displays current context within the input content for error tracking
Packit Service a31ea6
 */
Packit Service a31ea6
Packit Service a31ea6
static void
Packit Service a31ea6
xmlParserPrintFileContextInternal(xmlParserInputPtr input ,
Packit Service a31ea6
		xmlGenericErrorFunc chanl, void *data ) {
Packit Service a31ea6
    const xmlChar *cur, *base;
Packit Service a31ea6
    unsigned int n, col;	/* GCC warns if signed, because compared with sizeof() */
Packit Service a31ea6
    xmlChar  content[81]; /* space for 80 chars + line terminator */
Packit Service a31ea6
    xmlChar *ctnt;
Packit Service a31ea6
Packit Service a31ea6
    if (input == NULL) return;
Packit Service a31ea6
    cur = input->cur;
Packit Service a31ea6
    base = input->base;
Packit Service a31ea6
    /* skip backwards over any end-of-lines */
Packit Service a31ea6
    while ((cur > base) && ((*(cur) == '\n') || (*(cur) == '\r'))) {
Packit Service a31ea6
	cur--;
Packit Service a31ea6
    }
Packit Service a31ea6
    n = 0;
Packit Service a31ea6
    /* search backwards for beginning-of-line (to max buff size) */
Packit Service a31ea6
    while ((n++ < (sizeof(content)-1)) && (cur > base) &&
Packit Service a31ea6
   (*(cur) != '\n') && (*(cur) != '\r'))
Packit Service a31ea6
        cur--;
Packit Service a31ea6
    if ((*(cur) == '\n') || (*(cur) == '\r')) cur++;
Packit Service a31ea6
    /* calculate the error position in terms of the current position */
Packit Service a31ea6
    col = input->cur - cur;
Packit Service a31ea6
    /* search forward for end-of-line (to max buff size) */
Packit Service a31ea6
    n = 0;
Packit Service a31ea6
    ctnt = content;
Packit Service a31ea6
    /* copy selected text to our buffer */
Packit Service a31ea6
    while ((*cur != 0) && (*(cur) != '\n') &&
Packit Service a31ea6
   (*(cur) != '\r') && (n < sizeof(content)-1)) {
Packit Service a31ea6
		*ctnt++ = *cur++;
Packit Service a31ea6
	n++;
Packit Service a31ea6
    }
Packit Service a31ea6
    *ctnt = 0;
Packit Service a31ea6
    /* print out the selected text */
Packit Service a31ea6
    chanl(data ,"%s\n", content);
Packit Service a31ea6
    /* create blank line with problem pointer */
Packit Service a31ea6
    n = 0;
Packit Service a31ea6
    ctnt = content;
Packit Service a31ea6
    /* (leave buffer space for pointer + line terminator) */
Packit Service a31ea6
    while ((n
Packit Service a31ea6
	if (*(ctnt) != '\t')
Packit Service a31ea6
	    *(ctnt) = ' ';
Packit Service a31ea6
	ctnt++;
Packit Service a31ea6
    }
Packit Service a31ea6
    *ctnt++ = '^';
Packit Service a31ea6
    *ctnt = 0;
Packit Service a31ea6
    chanl(data ,"%s\n", content);
Packit Service a31ea6
}
Packit Service a31ea6
Packit Service a31ea6
static void
Packit Service a31ea6
testStructuredErrorHandler(void *ctx  ATTRIBUTE_UNUSED, xmlErrorPtr err) {
Packit Service a31ea6
    char *file = NULL;
Packit Service a31ea6
    int line = 0;
Packit Service a31ea6
    int code = -1;
Packit Service a31ea6
    int domain;
Packit Service a31ea6
    void *data = NULL;
Packit Service a31ea6
    const char *str;
Packit Service a31ea6
    const xmlChar *name = NULL;
Packit Service a31ea6
    xmlNodePtr node;
Packit Service a31ea6
    xmlErrorLevel level;
Packit Service a31ea6
    xmlParserInputPtr input = NULL;
Packit Service a31ea6
    xmlParserInputPtr cur = NULL;
Packit Service a31ea6
    xmlParserCtxtPtr ctxt = NULL;
Packit Service a31ea6
Packit Service a31ea6
    if (err == NULL)
Packit Service a31ea6
        return;
Packit Service a31ea6
Packit Service a31ea6
    file = err->file;
Packit Service a31ea6
    line = err->line;
Packit Service a31ea6
    code = err->code;
Packit Service a31ea6
    domain = err->domain;
Packit Service a31ea6
    level = err->level;
Packit Service a31ea6
    node = err->node;
Packit Service a31ea6
    if ((domain == XML_FROM_PARSER) || (domain == XML_FROM_HTML) ||
Packit Service a31ea6
        (domain == XML_FROM_DTD) || (domain == XML_FROM_NAMESPACE) ||
Packit Service a31ea6
	(domain == XML_FROM_IO) || (domain == XML_FROM_VALID)) {
Packit Service a31ea6
	ctxt = err->ctxt;
Packit Service a31ea6
    }
Packit Service a31ea6
    str = err->message;
Packit Service a31ea6
Packit Service a31ea6
    if (code == XML_ERR_OK)
Packit Service a31ea6
        return;
Packit Service a31ea6
Packit Service a31ea6
    if ((node != NULL) && (node->type == XML_ELEMENT_NODE))
Packit Service a31ea6
        name = node->name;
Packit Service a31ea6
Packit Service a31ea6
    /*
Packit Service a31ea6
     * Maintain the compatibility with the legacy error handling
Packit Service a31ea6
     */
Packit Service a31ea6
    if (ctxt != NULL) {
Packit Service a31ea6
        input = ctxt->input;
Packit Service a31ea6
        if ((input != NULL) && (input->filename == NULL) &&
Packit Service a31ea6
            (ctxt->inputNr > 1)) {
Packit Service a31ea6
            cur = input;
Packit Service a31ea6
            input = ctxt->inputTab[ctxt->inputNr - 2];
Packit Service a31ea6
        }
Packit Service a31ea6
        if (input != NULL) {
Packit Service a31ea6
            if (input->filename)
Packit Service a31ea6
                channel(data, "%s:%d: ", input->filename, input->line);
Packit Service a31ea6
            else if ((line != 0) && (domain == XML_FROM_PARSER))
Packit Service a31ea6
                channel(data, "Entity: line %d: ", input->line);
Packit Service a31ea6
        }
Packit Service a31ea6
    } else {
Packit Service a31ea6
        if (file != NULL)
Packit Service a31ea6
            channel(data, "%s:%d: ", file, line);
Packit Service a31ea6
        else if ((line != 0) && (domain == XML_FROM_PARSER))
Packit Service a31ea6
            channel(data, "Entity: line %d: ", line);
Packit Service a31ea6
    }
Packit Service a31ea6
    if (name != NULL) {
Packit Service a31ea6
        channel(data, "element %s: ", name);
Packit Service a31ea6
    }
Packit Service a31ea6
    if (code == XML_ERR_OK)
Packit Service a31ea6
        return;
Packit Service a31ea6
    switch (domain) {
Packit Service a31ea6
        case XML_FROM_PARSER:
Packit Service a31ea6
            channel(data, "parser ");
Packit Service a31ea6
            break;
Packit Service a31ea6
        case XML_FROM_NAMESPACE:
Packit Service a31ea6
            channel(data, "namespace ");
Packit Service a31ea6
            break;
Packit Service a31ea6
        case XML_FROM_DTD:
Packit Service a31ea6
        case XML_FROM_VALID:
Packit Service a31ea6
            channel(data, "validity ");
Packit Service a31ea6
            break;
Packit Service a31ea6
        case XML_FROM_HTML:
Packit Service a31ea6
            channel(data, "HTML parser ");
Packit Service a31ea6
            break;
Packit Service a31ea6
        case XML_FROM_MEMORY:
Packit Service a31ea6
            channel(data, "memory ");
Packit Service a31ea6
            break;
Packit Service a31ea6
        case XML_FROM_OUTPUT:
Packit Service a31ea6
            channel(data, "output ");
Packit Service a31ea6
            break;
Packit Service a31ea6
        case XML_FROM_IO:
Packit Service a31ea6
            channel(data, "I/O ");
Packit Service a31ea6
            break;
Packit Service a31ea6
        case XML_FROM_XINCLUDE:
Packit Service a31ea6
            channel(data, "XInclude ");
Packit Service a31ea6
            break;
Packit Service a31ea6
        case XML_FROM_XPATH:
Packit Service a31ea6
            channel(data, "XPath ");
Packit Service a31ea6
            break;
Packit Service a31ea6
        case XML_FROM_XPOINTER:
Packit Service a31ea6
            channel(data, "parser ");
Packit Service a31ea6
            break;
Packit Service a31ea6
        case XML_FROM_REGEXP:
Packit Service a31ea6
            channel(data, "regexp ");
Packit Service a31ea6
            break;
Packit Service a31ea6
        case XML_FROM_MODULE:
Packit Service a31ea6
            channel(data, "module ");
Packit Service a31ea6
            break;
Packit Service a31ea6
        case XML_FROM_SCHEMASV:
Packit Service a31ea6
            channel(data, "Schemas validity ");
Packit Service a31ea6
            break;
Packit Service a31ea6
        case XML_FROM_SCHEMASP:
Packit Service a31ea6
            channel(data, "Schemas parser ");
Packit Service a31ea6
            break;
Packit Service a31ea6
        case XML_FROM_RELAXNGP:
Packit Service a31ea6
            channel(data, "Relax-NG parser ");
Packit Service a31ea6
            break;
Packit Service a31ea6
        case XML_FROM_RELAXNGV:
Packit Service a31ea6
            channel(data, "Relax-NG validity ");
Packit Service a31ea6
            break;
Packit Service a31ea6
        case XML_FROM_CATALOG:
Packit Service a31ea6
            channel(data, "Catalog ");
Packit Service a31ea6
            break;
Packit Service a31ea6
        case XML_FROM_C14N:
Packit Service a31ea6
            channel(data, "C14N ");
Packit Service a31ea6
            break;
Packit Service a31ea6
        case XML_FROM_XSLT:
Packit Service a31ea6
            channel(data, "XSLT ");
Packit Service a31ea6
            break;
Packit Service a31ea6
        default:
Packit Service a31ea6
            break;
Packit Service a31ea6
    }
Packit Service a31ea6
    if (code == XML_ERR_OK)
Packit Service a31ea6
        return;
Packit Service a31ea6
    switch (level) {
Packit Service a31ea6
        case XML_ERR_NONE:
Packit Service a31ea6
            channel(data, ": ");
Packit Service a31ea6
            break;
Packit Service a31ea6
        case XML_ERR_WARNING:
Packit Service a31ea6
            channel(data, "warning : ");
Packit Service a31ea6
            break;
Packit Service a31ea6
        case XML_ERR_ERROR:
Packit Service a31ea6
            channel(data, "error : ");
Packit Service a31ea6
            break;
Packit Service a31ea6
        case XML_ERR_FATAL:
Packit Service a31ea6
            channel(data, "error : ");
Packit Service a31ea6
            break;
Packit Service a31ea6
    }
Packit Service a31ea6
    if (code == XML_ERR_OK)
Packit Service a31ea6
        return;
Packit Service a31ea6
    if (str != NULL) {
Packit Service a31ea6
        int len;
Packit Service a31ea6
	len = xmlStrlen((const xmlChar *)str);
Packit Service a31ea6
	if ((len > 0) && (str[len - 1] != '\n'))
Packit Service a31ea6
	    channel(data, "%s\n", str);
Packit Service a31ea6
	else
Packit Service a31ea6
	    channel(data, "%s", str);
Packit Service a31ea6
    } else {
Packit Service a31ea6
        channel(data, "%s\n", "out of memory error");
Packit Service a31ea6
    }
Packit Service a31ea6
    if (code == XML_ERR_OK)
Packit Service a31ea6
        return;
Packit Service a31ea6
Packit Service a31ea6
    if (ctxt != NULL) {
Packit Service a31ea6
        xmlParserPrintFileContextInternal(input, channel, data);
Packit Service a31ea6
        if (cur != NULL) {
Packit Service a31ea6
            if (cur->filename)
Packit Service a31ea6
                channel(data, "%s:%d: \n", cur->filename, cur->line);
Packit Service a31ea6
            else if ((line != 0) && (domain == XML_FROM_PARSER))
Packit Service a31ea6
                channel(data, "Entity: line %d: \n", cur->line);
Packit Service a31ea6
            xmlParserPrintFileContextInternal(cur, channel, data);
Packit Service a31ea6
        }
Packit Service a31ea6
    }
Packit Service a31ea6
    if ((domain == XML_FROM_XPATH) && (err->str1 != NULL) &&
Packit Service a31ea6
        (err->int1 < 100) &&
Packit Service a31ea6
	(err->int1 < xmlStrlen((const xmlChar *)err->str1))) {
Packit Service a31ea6
	xmlChar buf[150];
Packit Service a31ea6
	int i;
Packit Service a31ea6
Packit Service a31ea6
	channel(data, "%s\n", err->str1);
Packit Service a31ea6
	for (i=0;i < err->int1;i++)
Packit Service a31ea6
	     buf[i] = ' ';
Packit Service a31ea6
	buf[i++] = '^';
Packit Service a31ea6
	buf[i] = 0;
Packit Service a31ea6
	channel(data, "%s\n", buf);
Packit Service a31ea6
    }
Packit Service a31ea6
}
Packit Service a31ea6
Packit Service a31ea6
static void
Packit Service a31ea6
initializeLibxml2(void) {
Packit Service a31ea6
    xmlGetWarningsDefaultValue = 0;
Packit Service a31ea6
    xmlPedanticParserDefault(0);
Packit Service a31ea6
Packit Service a31ea6
    xmlMemSetup(xmlMemFree, xmlMemMalloc, xmlMemRealloc, xmlMemoryStrdup);
Packit Service a31ea6
    xmlInitParser();
Packit Service a31ea6
    xmlSetExternalEntityLoader(testExternalEntityLoader);
Packit Service a31ea6
    xmlSetStructuredErrorFunc(NULL, testStructuredErrorHandler);
Packit Service a31ea6
    /*
Packit Service a31ea6
     * register the new I/O handlers
Packit Service a31ea6
     */
Packit Service a31ea6
    if (xmlRegisterInputCallbacks(hugeMatch, hugeOpen,
Packit Service a31ea6
                                  hugeRead, hugeClose) < 0) {
Packit Service a31ea6
        fprintf(stderr, "failed to register Huge handlers\n");
Packit Service a31ea6
	exit(1);
Packit Service a31ea6
    }
Packit Service a31ea6
    if (xmlRegisterInputCallbacks(crazyMatch, crazyOpen,
Packit Service a31ea6
                                  crazyRead, crazyClose) < 0) {
Packit Service a31ea6
        fprintf(stderr, "failed to register Crazy handlers\n");
Packit Service a31ea6
	exit(1);
Packit Service a31ea6
    }
Packit Service a31ea6
}
Packit Service a31ea6
Packit Service a31ea6
/************************************************************************
Packit Service a31ea6
 *									*
Packit Service a31ea6
 *		SAX empty callbacks                                     *
Packit Service a31ea6
 *									*
Packit Service a31ea6
 ************************************************************************/
Packit Service a31ea6
Packit Service a31ea6
unsigned long callbacks = 0;
Packit Service a31ea6
Packit Service a31ea6
/**
Packit Service a31ea6
 * isStandaloneCallback:
Packit Service a31ea6
 * @ctxt:  An XML parser context
Packit Service a31ea6
 *
Packit Service a31ea6
 * Is this document tagged standalone ?
Packit Service a31ea6
 *
Packit Service a31ea6
 * Returns 1 if true
Packit Service a31ea6
 */
Packit Service a31ea6
static int
Packit Service a31ea6
isStandaloneCallback(void *ctx ATTRIBUTE_UNUSED)
Packit Service a31ea6
{
Packit Service a31ea6
    callbacks++;
Packit Service a31ea6
    return (0);
Packit Service a31ea6
}
Packit Service a31ea6
Packit Service a31ea6
/**
Packit Service a31ea6
 * hasInternalSubsetCallback:
Packit Service a31ea6
 * @ctxt:  An XML parser context
Packit Service a31ea6
 *
Packit Service a31ea6
 * Does this document has an internal subset
Packit Service a31ea6
 *
Packit Service a31ea6
 * Returns 1 if true
Packit Service a31ea6
 */
Packit Service a31ea6
static int
Packit Service a31ea6
hasInternalSubsetCallback(void *ctx ATTRIBUTE_UNUSED)
Packit Service a31ea6
{
Packit Service a31ea6
    callbacks++;
Packit Service a31ea6
    return (0);
Packit Service a31ea6
}
Packit Service a31ea6
Packit Service a31ea6
/**
Packit Service a31ea6
 * hasExternalSubsetCallback:
Packit Service a31ea6
 * @ctxt:  An XML parser context
Packit Service a31ea6
 *
Packit Service a31ea6
 * Does this document has an external subset
Packit Service a31ea6
 *
Packit Service a31ea6
 * Returns 1 if true
Packit Service a31ea6
 */
Packit Service a31ea6
static int
Packit Service a31ea6
hasExternalSubsetCallback(void *ctx ATTRIBUTE_UNUSED)
Packit Service a31ea6
{
Packit Service a31ea6
    callbacks++;
Packit Service a31ea6
    return (0);
Packit Service a31ea6
}
Packit Service a31ea6
Packit Service a31ea6
/**
Packit Service a31ea6
 * internalSubsetCallback:
Packit Service a31ea6
 * @ctxt:  An XML parser context
Packit Service a31ea6
 *
Packit Service a31ea6
 * Does this document has an internal subset
Packit Service a31ea6
 */
Packit Service a31ea6
static void
Packit Service a31ea6
internalSubsetCallback(void *ctx ATTRIBUTE_UNUSED,
Packit Service a31ea6
                       const xmlChar * name ATTRIBUTE_UNUSED,
Packit Service a31ea6
                       const xmlChar * ExternalID ATTRIBUTE_UNUSED,
Packit Service a31ea6
                       const xmlChar * SystemID ATTRIBUTE_UNUSED)
Packit Service a31ea6
{
Packit Service a31ea6
    callbacks++;
Packit Service a31ea6
    return;
Packit Service a31ea6
}
Packit Service a31ea6
Packit Service a31ea6
/**
Packit Service a31ea6
 * externalSubsetCallback:
Packit Service a31ea6
 * @ctxt:  An XML parser context
Packit Service a31ea6
 *
Packit Service a31ea6
 * Does this document has an external subset
Packit Service a31ea6
 */
Packit Service a31ea6
static void
Packit Service a31ea6
externalSubsetCallback(void *ctx ATTRIBUTE_UNUSED,
Packit Service a31ea6
                       const xmlChar * name ATTRIBUTE_UNUSED,
Packit Service a31ea6
                       const xmlChar * ExternalID ATTRIBUTE_UNUSED,
Packit Service a31ea6
                       const xmlChar * SystemID ATTRIBUTE_UNUSED)
Packit Service a31ea6
{
Packit Service a31ea6
    callbacks++;
Packit Service a31ea6
    return;
Packit Service a31ea6
}
Packit Service a31ea6
Packit Service a31ea6
/**
Packit Service a31ea6
 * resolveEntityCallback:
Packit Service a31ea6
 * @ctxt:  An XML parser context
Packit Service a31ea6
 * @publicId: The public ID of the entity
Packit Service a31ea6
 * @systemId: The system ID of the entity
Packit Service a31ea6
 *
Packit Service a31ea6
 * Special entity resolver, better left to the parser, it has
Packit Service a31ea6
 * more context than the application layer.
Packit Service a31ea6
 * The default behaviour is to NOT resolve the entities, in that case
Packit Service a31ea6
 * the ENTITY_REF nodes are built in the structure (and the parameter
Packit Service a31ea6
 * values).
Packit Service a31ea6
 *
Packit Service a31ea6
 * Returns the xmlParserInputPtr if inlined or NULL for DOM behaviour.
Packit Service a31ea6
 */
Packit Service a31ea6
static xmlParserInputPtr
Packit Service a31ea6
resolveEntityCallback(void *ctx ATTRIBUTE_UNUSED,
Packit Service a31ea6
                      const xmlChar * publicId ATTRIBUTE_UNUSED,
Packit Service a31ea6
                      const xmlChar * systemId ATTRIBUTE_UNUSED)
Packit Service a31ea6
{
Packit Service a31ea6
    callbacks++;
Packit Service a31ea6
    return (NULL);
Packit Service a31ea6
}
Packit Service a31ea6
Packit Service a31ea6
/**
Packit Service a31ea6
 * getEntityCallback:
Packit Service a31ea6
 * @ctxt:  An XML parser context
Packit Service a31ea6
 * @name: The entity name
Packit Service a31ea6
 *
Packit Service a31ea6
 * Get an entity by name
Packit Service a31ea6
 *
Packit Service a31ea6
 * Returns the xmlParserInputPtr if inlined or NULL for DOM behaviour.
Packit Service a31ea6
 */
Packit Service a31ea6
static xmlEntityPtr
Packit Service a31ea6
getEntityCallback(void *ctx ATTRIBUTE_UNUSED,
Packit Service a31ea6
                  const xmlChar * name ATTRIBUTE_UNUSED)
Packit Service a31ea6
{
Packit Service a31ea6
    callbacks++;
Packit Service a31ea6
    return (NULL);
Packit Service a31ea6
}
Packit Service a31ea6
Packit Service a31ea6
/**
Packit Service a31ea6
 * getParameterEntityCallback:
Packit Service a31ea6
 * @ctxt:  An XML parser context
Packit Service a31ea6
 * @name: The entity name
Packit Service a31ea6
 *
Packit Service a31ea6
 * Get a parameter entity by name
Packit Service a31ea6
 *
Packit Service a31ea6
 * Returns the xmlParserInputPtr
Packit Service a31ea6
 */
Packit Service a31ea6
static xmlEntityPtr
Packit Service a31ea6
getParameterEntityCallback(void *ctx ATTRIBUTE_UNUSED,
Packit Service a31ea6
                           const xmlChar * name ATTRIBUTE_UNUSED)
Packit Service a31ea6
{
Packit Service a31ea6
    callbacks++;
Packit Service a31ea6
    return (NULL);
Packit Service a31ea6
}
Packit Service a31ea6
Packit Service a31ea6
Packit Service a31ea6
/**
Packit Service a31ea6
 * entityDeclCallback:
Packit Service a31ea6
 * @ctxt:  An XML parser context
Packit Service a31ea6
 * @name:  the entity name
Packit Service a31ea6
 * @type:  the entity type
Packit Service a31ea6
 * @publicId: The public ID of the entity
Packit Service a31ea6
 * @systemId: The system ID of the entity
Packit Service a31ea6
 * @content: the entity value (without processing).
Packit Service a31ea6
 *
Packit Service a31ea6
 * An entity definition has been parsed
Packit Service a31ea6
 */
Packit Service a31ea6
static void
Packit Service a31ea6
entityDeclCallback(void *ctx ATTRIBUTE_UNUSED,
Packit Service a31ea6
                   const xmlChar * name ATTRIBUTE_UNUSED,
Packit Service a31ea6
                   int type ATTRIBUTE_UNUSED,
Packit Service a31ea6
                   const xmlChar * publicId ATTRIBUTE_UNUSED,
Packit Service a31ea6
                   const xmlChar * systemId ATTRIBUTE_UNUSED,
Packit Service a31ea6
                   xmlChar * content ATTRIBUTE_UNUSED)
Packit Service a31ea6
{
Packit Service a31ea6
    callbacks++;
Packit Service a31ea6
    return;
Packit Service a31ea6
}
Packit Service a31ea6
Packit Service a31ea6
/**
Packit Service a31ea6
 * attributeDeclCallback:
Packit Service a31ea6
 * @ctxt:  An XML parser context
Packit Service a31ea6
 * @name:  the attribute name
Packit Service a31ea6
 * @type:  the attribute type
Packit Service a31ea6
 *
Packit Service a31ea6
 * An attribute definition has been parsed
Packit Service a31ea6
 */
Packit Service a31ea6
static void
Packit Service a31ea6
attributeDeclCallback(void *ctx ATTRIBUTE_UNUSED,
Packit Service a31ea6
                      const xmlChar * elem ATTRIBUTE_UNUSED,
Packit Service a31ea6
                      const xmlChar * name ATTRIBUTE_UNUSED,
Packit Service a31ea6
                      int type ATTRIBUTE_UNUSED, int def ATTRIBUTE_UNUSED,
Packit Service a31ea6
                      const xmlChar * defaultValue ATTRIBUTE_UNUSED,
Packit Service a31ea6
                      xmlEnumerationPtr tree ATTRIBUTE_UNUSED)
Packit Service a31ea6
{
Packit Service a31ea6
    callbacks++;
Packit Service a31ea6
    return;
Packit Service a31ea6
}
Packit Service a31ea6
Packit Service a31ea6
/**
Packit Service a31ea6
 * elementDeclCallback:
Packit Service a31ea6
 * @ctxt:  An XML parser context
Packit Service a31ea6
 * @name:  the element name
Packit Service a31ea6
 * @type:  the element type
Packit Service a31ea6
 * @content: the element value (without processing).
Packit Service a31ea6
 *
Packit Service a31ea6
 * An element definition has been parsed
Packit Service a31ea6
 */
Packit Service a31ea6
static void
Packit Service a31ea6
elementDeclCallback(void *ctx ATTRIBUTE_UNUSED,
Packit Service a31ea6
                    const xmlChar * name ATTRIBUTE_UNUSED,
Packit Service a31ea6
                    int type ATTRIBUTE_UNUSED,
Packit Service a31ea6
                    xmlElementContentPtr content ATTRIBUTE_UNUSED)
Packit Service a31ea6
{
Packit Service a31ea6
    callbacks++;
Packit Service a31ea6
    return;
Packit Service a31ea6
}
Packit Service a31ea6
Packit Service a31ea6
/**
Packit Service a31ea6
 * notationDeclCallback:
Packit Service a31ea6
 * @ctxt:  An XML parser context
Packit Service a31ea6
 * @name: The name of the notation
Packit Service a31ea6
 * @publicId: The public ID of the entity
Packit Service a31ea6
 * @systemId: The system ID of the entity
Packit Service a31ea6
 *
Packit Service a31ea6
 * What to do when a notation declaration has been parsed.
Packit Service a31ea6
 */
Packit Service a31ea6
static void
Packit Service a31ea6
notationDeclCallback(void *ctx ATTRIBUTE_UNUSED,
Packit Service a31ea6
                     const xmlChar * name ATTRIBUTE_UNUSED,
Packit Service a31ea6
                     const xmlChar * publicId ATTRIBUTE_UNUSED,
Packit Service a31ea6
                     const xmlChar * systemId ATTRIBUTE_UNUSED)
Packit Service a31ea6
{
Packit Service a31ea6
    callbacks++;
Packit Service a31ea6
    return;
Packit Service a31ea6
}
Packit Service a31ea6
Packit Service a31ea6
/**
Packit Service a31ea6
 * unparsedEntityDeclCallback:
Packit Service a31ea6
 * @ctxt:  An XML parser context
Packit Service a31ea6
 * @name: The name of the entity
Packit Service a31ea6
 * @publicId: The public ID of the entity
Packit Service a31ea6
 * @systemId: The system ID of the entity
Packit Service a31ea6
 * @notationName: the name of the notation
Packit Service a31ea6
 *
Packit Service a31ea6
 * What to do when an unparsed entity declaration is parsed
Packit Service a31ea6
 */
Packit Service a31ea6
static void
Packit Service a31ea6
unparsedEntityDeclCallback(void *ctx ATTRIBUTE_UNUSED,
Packit Service a31ea6
                           const xmlChar * name ATTRIBUTE_UNUSED,
Packit Service a31ea6
                           const xmlChar * publicId ATTRIBUTE_UNUSED,
Packit Service a31ea6
                           const xmlChar * systemId ATTRIBUTE_UNUSED,
Packit Service a31ea6
                           const xmlChar * notationName ATTRIBUTE_UNUSED)
Packit Service a31ea6
{
Packit Service a31ea6
    callbacks++;
Packit Service a31ea6
    return;
Packit Service a31ea6
}
Packit Service a31ea6
Packit Service a31ea6
/**
Packit Service a31ea6
 * setDocumentLocatorCallback:
Packit Service a31ea6
 * @ctxt:  An XML parser context
Packit Service a31ea6
 * @loc: A SAX Locator
Packit Service a31ea6
 *
Packit Service a31ea6
 * Receive the document locator at startup, actually xmlDefaultSAXLocator
Packit Service a31ea6
 * Everything is available on the context, so this is useless in our case.
Packit Service a31ea6
 */
Packit Service a31ea6
static void
Packit Service a31ea6
setDocumentLocatorCallback(void *ctx ATTRIBUTE_UNUSED,
Packit Service a31ea6
                           xmlSAXLocatorPtr loc ATTRIBUTE_UNUSED)
Packit Service a31ea6
{
Packit Service a31ea6
    callbacks++;
Packit Service a31ea6
    return;
Packit Service a31ea6
}
Packit Service a31ea6
Packit Service a31ea6
/**
Packit Service a31ea6
 * startDocumentCallback:
Packit Service a31ea6
 * @ctxt:  An XML parser context
Packit Service a31ea6
 *
Packit Service a31ea6
 * called when the document start being processed.
Packit Service a31ea6
 */
Packit Service a31ea6
static void
Packit Service a31ea6
startDocumentCallback(void *ctx ATTRIBUTE_UNUSED)
Packit Service a31ea6
{
Packit Service a31ea6
    callbacks++;
Packit Service a31ea6
    return;
Packit Service a31ea6
}
Packit Service a31ea6
Packit Service a31ea6
/**
Packit Service a31ea6
 * endDocumentCallback:
Packit Service a31ea6
 * @ctxt:  An XML parser context
Packit Service a31ea6
 *
Packit Service a31ea6
 * called when the document end has been detected.
Packit Service a31ea6
 */
Packit Service a31ea6
static void
Packit Service a31ea6
endDocumentCallback(void *ctx ATTRIBUTE_UNUSED)
Packit Service a31ea6
{
Packit Service a31ea6
    callbacks++;
Packit Service a31ea6
    return;
Packit Service a31ea6
}
Packit Service a31ea6
Packit Service a31ea6
#if 0
Packit Service a31ea6
/**
Packit Service a31ea6
 * startElementCallback:
Packit Service a31ea6
 * @ctxt:  An XML parser context
Packit Service a31ea6
 * @name:  The element name
Packit Service a31ea6
 *
Packit Service a31ea6
 * called when an opening tag has been processed.
Packit Service a31ea6
 */
Packit Service a31ea6
static void
Packit Service a31ea6
startElementCallback(void *ctx ATTRIBUTE_UNUSED,
Packit Service a31ea6
                     const xmlChar * name ATTRIBUTE_UNUSED,
Packit Service a31ea6
                     const xmlChar ** atts ATTRIBUTE_UNUSED)
Packit Service a31ea6
{
Packit Service a31ea6
    callbacks++;
Packit Service a31ea6
    return;
Packit Service a31ea6
}
Packit Service a31ea6
Packit Service a31ea6
/**
Packit Service a31ea6
 * endElementCallback:
Packit Service a31ea6
 * @ctxt:  An XML parser context
Packit Service a31ea6
 * @name:  The element name
Packit Service a31ea6
 *
Packit Service a31ea6
 * called when the end of an element has been detected.
Packit Service a31ea6
 */
Packit Service a31ea6
static void
Packit Service a31ea6
endElementCallback(void *ctx ATTRIBUTE_UNUSED,
Packit Service a31ea6
                   const xmlChar * name ATTRIBUTE_UNUSED)
Packit Service a31ea6
{
Packit Service a31ea6
    callbacks++;
Packit Service a31ea6
    return;
Packit Service a31ea6
}
Packit Service a31ea6
#endif
Packit Service a31ea6
Packit Service a31ea6
/**
Packit Service a31ea6
 * charactersCallback:
Packit Service a31ea6
 * @ctxt:  An XML parser context
Packit Service a31ea6
 * @ch:  a xmlChar string
Packit Service a31ea6
 * @len: the number of xmlChar
Packit Service a31ea6
 *
Packit Service a31ea6
 * receiving some chars from the parser.
Packit Service a31ea6
 * Question: how much at a time ???
Packit Service a31ea6
 */
Packit Service a31ea6
static void
Packit Service a31ea6
charactersCallback(void *ctx ATTRIBUTE_UNUSED,
Packit Service a31ea6
                   const xmlChar * ch ATTRIBUTE_UNUSED,
Packit Service a31ea6
                   int len ATTRIBUTE_UNUSED)
Packit Service a31ea6
{
Packit Service a31ea6
    callbacks++;
Packit Service a31ea6
    return;
Packit Service a31ea6
}
Packit Service a31ea6
Packit Service a31ea6
/**
Packit Service a31ea6
 * referenceCallback:
Packit Service a31ea6
 * @ctxt:  An XML parser context
Packit Service a31ea6
 * @name:  The entity name
Packit Service a31ea6
 *
Packit Service a31ea6
 * called when an entity reference is detected.
Packit Service a31ea6
 */
Packit Service a31ea6
static void
Packit Service a31ea6
referenceCallback(void *ctx ATTRIBUTE_UNUSED,
Packit Service a31ea6
                  const xmlChar * name ATTRIBUTE_UNUSED)
Packit Service a31ea6
{
Packit Service a31ea6
    callbacks++;
Packit Service a31ea6
    return;
Packit Service a31ea6
}
Packit Service a31ea6
Packit Service a31ea6
/**
Packit Service a31ea6
 * ignorableWhitespaceCallback:
Packit Service a31ea6
 * @ctxt:  An XML parser context
Packit Service a31ea6
 * @ch:  a xmlChar string
Packit Service a31ea6
 * @start: the first char in the string
Packit Service a31ea6
 * @len: the number of xmlChar
Packit Service a31ea6
 *
Packit Service a31ea6
 * receiving some ignorable whitespaces from the parser.
Packit Service a31ea6
 * Question: how much at a time ???
Packit Service a31ea6
 */
Packit Service a31ea6
static void
Packit Service a31ea6
ignorableWhitespaceCallback(void *ctx ATTRIBUTE_UNUSED,
Packit Service a31ea6
                            const xmlChar * ch ATTRIBUTE_UNUSED,
Packit Service a31ea6
                            int len ATTRIBUTE_UNUSED)
Packit Service a31ea6
{
Packit Service a31ea6
    callbacks++;
Packit Service a31ea6
    return;
Packit Service a31ea6
}
Packit Service a31ea6
Packit Service a31ea6
/**
Packit Service a31ea6
 * processingInstructionCallback:
Packit Service a31ea6
 * @ctxt:  An XML parser context
Packit Service a31ea6
 * @target:  the target name
Packit Service a31ea6
 * @data: the PI data's
Packit Service a31ea6
 * @len: the number of xmlChar
Packit Service a31ea6
 *
Packit Service a31ea6
 * A processing instruction has been parsed.
Packit Service a31ea6
 */
Packit Service a31ea6
static void
Packit Service a31ea6
processingInstructionCallback(void *ctx ATTRIBUTE_UNUSED,
Packit Service a31ea6
                              const xmlChar * target ATTRIBUTE_UNUSED,
Packit Service a31ea6
                              const xmlChar * data ATTRIBUTE_UNUSED)
Packit Service a31ea6
{
Packit Service a31ea6
    callbacks++;
Packit Service a31ea6
    return;
Packit Service a31ea6
}
Packit Service a31ea6
Packit Service a31ea6
/**
Packit Service a31ea6
 * cdataBlockCallback:
Packit Service a31ea6
 * @ctx: the user data (XML parser context)
Packit Service a31ea6
 * @value:  The pcdata content
Packit Service a31ea6
 * @len:  the block length
Packit Service a31ea6
 *
Packit Service a31ea6
 * called when a pcdata block has been parsed
Packit Service a31ea6
 */
Packit Service a31ea6
static void
Packit Service a31ea6
cdataBlockCallback(void *ctx ATTRIBUTE_UNUSED,
Packit Service a31ea6
                   const xmlChar * value ATTRIBUTE_UNUSED,
Packit Service a31ea6
                   int len ATTRIBUTE_UNUSED)
Packit Service a31ea6
{
Packit Service a31ea6
    callbacks++;
Packit Service a31ea6
    return;
Packit Service a31ea6
}
Packit Service a31ea6
Packit Service a31ea6
/**
Packit Service a31ea6
 * commentCallback:
Packit Service a31ea6
 * @ctxt:  An XML parser context
Packit Service a31ea6
 * @value:  the comment content
Packit Service a31ea6
 *
Packit Service a31ea6
 * A comment has been parsed.
Packit Service a31ea6
 */
Packit Service a31ea6
static void
Packit Service a31ea6
commentCallback(void *ctx ATTRIBUTE_UNUSED,
Packit Service a31ea6
                const xmlChar * value ATTRIBUTE_UNUSED)
Packit Service a31ea6
{
Packit Service a31ea6
    callbacks++;
Packit Service a31ea6
    return;
Packit Service a31ea6
}
Packit Service a31ea6
Packit Service a31ea6
/**
Packit Service a31ea6
 * warningCallback:
Packit Service a31ea6
 * @ctxt:  An XML parser context
Packit Service a31ea6
 * @msg:  the message to display/transmit
Packit Service a31ea6
 * @...:  extra parameters for the message display
Packit Service a31ea6
 *
Packit Service a31ea6
 * Display and format a warning messages, gives file, line, position and
Packit Service a31ea6
 * extra parameters.
Packit Service a31ea6
 */
Packit Service a31ea6
static void XMLCDECL
Packit Service a31ea6
warningCallback(void *ctx ATTRIBUTE_UNUSED,
Packit Service a31ea6
                const char *msg ATTRIBUTE_UNUSED, ...)
Packit Service a31ea6
{
Packit Service a31ea6
    callbacks++;
Packit Service a31ea6
    return;
Packit Service a31ea6
}
Packit Service a31ea6
Packit Service a31ea6
/**
Packit Service a31ea6
 * errorCallback:
Packit Service a31ea6
 * @ctxt:  An XML parser context
Packit Service a31ea6
 * @msg:  the message to display/transmit
Packit Service a31ea6
 * @...:  extra parameters for the message display
Packit Service a31ea6
 *
Packit Service a31ea6
 * Display and format a error messages, gives file, line, position and
Packit Service a31ea6
 * extra parameters.
Packit Service a31ea6
 */
Packit Service a31ea6
static void XMLCDECL
Packit Service a31ea6
errorCallback(void *ctx ATTRIBUTE_UNUSED, const char *msg ATTRIBUTE_UNUSED,
Packit Service a31ea6
              ...)
Packit Service a31ea6
{
Packit Service a31ea6
    callbacks++;
Packit Service a31ea6
    return;
Packit Service a31ea6
}
Packit Service a31ea6
Packit Service a31ea6
/**
Packit Service a31ea6
 * fatalErrorCallback:
Packit Service a31ea6
 * @ctxt:  An XML parser context
Packit Service a31ea6
 * @msg:  the message to display/transmit
Packit Service a31ea6
 * @...:  extra parameters for the message display
Packit Service a31ea6
 *
Packit Service a31ea6
 * Display and format a fatalError messages, gives file, line, position and
Packit Service a31ea6
 * extra parameters.
Packit Service a31ea6
 */
Packit Service a31ea6
static void XMLCDECL
Packit Service a31ea6
fatalErrorCallback(void *ctx ATTRIBUTE_UNUSED,
Packit Service a31ea6
                   const char *msg ATTRIBUTE_UNUSED, ...)
Packit Service a31ea6
{
Packit Service a31ea6
    return;
Packit Service a31ea6
}
Packit Service a31ea6
Packit Service a31ea6
Packit Service a31ea6
/*
Packit Service a31ea6
 * SAX2 specific callbacks
Packit Service a31ea6
 */
Packit Service a31ea6
Packit Service a31ea6
/**
Packit Service a31ea6
 * startElementNsCallback:
Packit Service a31ea6
 * @ctxt:  An XML parser context
Packit Service a31ea6
 * @name:  The element name
Packit Service a31ea6
 *
Packit Service a31ea6
 * called when an opening tag has been processed.
Packit Service a31ea6
 */
Packit Service a31ea6
static void
Packit Service a31ea6
startElementNsCallback(void *ctx ATTRIBUTE_UNUSED,
Packit Service a31ea6
                       const xmlChar * localname ATTRIBUTE_UNUSED,
Packit Service a31ea6
                       const xmlChar * prefix ATTRIBUTE_UNUSED,
Packit Service a31ea6
                       const xmlChar * URI ATTRIBUTE_UNUSED,
Packit Service a31ea6
                       int nb_namespaces ATTRIBUTE_UNUSED,
Packit Service a31ea6
                       const xmlChar ** namespaces ATTRIBUTE_UNUSED,
Packit Service a31ea6
                       int nb_attributes ATTRIBUTE_UNUSED,
Packit Service a31ea6
                       int nb_defaulted ATTRIBUTE_UNUSED,
Packit Service a31ea6
                       const xmlChar ** attributes ATTRIBUTE_UNUSED)
Packit Service a31ea6
{
Packit Service a31ea6
    callbacks++;
Packit Service a31ea6
    return;
Packit Service a31ea6
}
Packit Service a31ea6
Packit Service a31ea6
/**
Packit Service a31ea6
 * endElementCallback:
Packit Service a31ea6
 * @ctxt:  An XML parser context
Packit Service a31ea6
 * @name:  The element name
Packit Service a31ea6
 *
Packit Service a31ea6
 * called when the end of an element has been detected.
Packit Service a31ea6
 */
Packit Service a31ea6
static void
Packit Service a31ea6
endElementNsCallback(void *ctx ATTRIBUTE_UNUSED,
Packit Service a31ea6
                     const xmlChar * localname ATTRIBUTE_UNUSED,
Packit Service a31ea6
                     const xmlChar * prefix ATTRIBUTE_UNUSED,
Packit Service a31ea6
                     const xmlChar * URI ATTRIBUTE_UNUSED)
Packit Service a31ea6
{
Packit Service a31ea6
    callbacks++;
Packit Service a31ea6
    return;
Packit Service a31ea6
}
Packit Service a31ea6
Packit Service a31ea6
static xmlSAXHandler callbackSAX2HandlerStruct = {
Packit Service a31ea6
    internalSubsetCallback,
Packit Service a31ea6
    isStandaloneCallback,
Packit Service a31ea6
    hasInternalSubsetCallback,
Packit Service a31ea6
    hasExternalSubsetCallback,
Packit Service a31ea6
    resolveEntityCallback,
Packit Service a31ea6
    getEntityCallback,
Packit Service a31ea6
    entityDeclCallback,
Packit Service a31ea6
    notationDeclCallback,
Packit Service a31ea6
    attributeDeclCallback,
Packit Service a31ea6
    elementDeclCallback,
Packit Service a31ea6
    unparsedEntityDeclCallback,
Packit Service a31ea6
    setDocumentLocatorCallback,
Packit Service a31ea6
    startDocumentCallback,
Packit Service a31ea6
    endDocumentCallback,
Packit Service a31ea6
    NULL,
Packit Service a31ea6
    NULL,
Packit Service a31ea6
    referenceCallback,
Packit Service a31ea6
    charactersCallback,
Packit Service a31ea6
    ignorableWhitespaceCallback,
Packit Service a31ea6
    processingInstructionCallback,
Packit Service a31ea6
    commentCallback,
Packit Service a31ea6
    warningCallback,
Packit Service a31ea6
    errorCallback,
Packit Service a31ea6
    fatalErrorCallback,
Packit Service a31ea6
    getParameterEntityCallback,
Packit Service a31ea6
    cdataBlockCallback,
Packit Service a31ea6
    externalSubsetCallback,
Packit Service a31ea6
    XML_SAX2_MAGIC,
Packit Service a31ea6
    NULL,
Packit Service a31ea6
    startElementNsCallback,
Packit Service a31ea6
    endElementNsCallback,
Packit Service a31ea6
    NULL
Packit Service a31ea6
};
Packit Service a31ea6
Packit Service a31ea6
static xmlSAXHandlerPtr callbackSAX2Handler = &callbackSAX2HandlerStruct;
Packit Service a31ea6
Packit Service a31ea6
/************************************************************************
Packit Service a31ea6
 *									*
Packit Service a31ea6
 *		The tests front-ends                                     *
Packit Service a31ea6
 *									*
Packit Service a31ea6
 ************************************************************************/
Packit Service a31ea6
Packit Service a31ea6
/**
Packit Service a31ea6
 * readerTest:
Packit Service a31ea6
 * @filename: the file to parse
Packit Service a31ea6
 * @max_size: size of the limit to test
Packit Service a31ea6
 * @options: parsing options
Packit Service a31ea6
 * @fail: should a failure be reported
Packit Service a31ea6
 *
Packit Service a31ea6
 * Parse a memory generated file using SAX
Packit Service a31ea6
 *
Packit Service a31ea6
 * Returns 0 in case of success, an error code otherwise
Packit Service a31ea6
 */
Packit Service a31ea6
static int
Packit Service a31ea6
saxTest(const char *filename, size_t limit, int options, int fail) {
Packit Service a31ea6
    int res = 0;
Packit Service a31ea6
    xmlParserCtxtPtr ctxt;
Packit Service a31ea6
    xmlDocPtr doc;
Packit Service a31ea6
    xmlSAXHandlerPtr old_sax;
Packit Service a31ea6
Packit Service a31ea6
    nb_tests++;
Packit Service a31ea6
Packit Service a31ea6
    maxlen = limit;
Packit Service a31ea6
    ctxt = xmlNewParserCtxt();
Packit Service a31ea6
    if (ctxt == NULL) {
Packit Service a31ea6
        fprintf(stderr, "Failed to create parser context\n");
Packit Service a31ea6
	return(1);
Packit Service a31ea6
    }
Packit Service a31ea6
    old_sax = ctxt->sax;
Packit Service a31ea6
    ctxt->sax = callbackSAX2Handler;
Packit Service a31ea6
    ctxt->userData = NULL;
Packit Service a31ea6
    doc = xmlCtxtReadFile(ctxt, filename, NULL, options);
Packit Service a31ea6
Packit Service a31ea6
    if (doc != NULL) {
Packit Service a31ea6
        fprintf(stderr, "SAX parsing generated a document !\n");
Packit Service a31ea6
        xmlFreeDoc(doc);
Packit Service a31ea6
        res = 0;
Packit Service a31ea6
    } else if (ctxt->wellFormed == 0) {
Packit Service a31ea6
        if (fail)
Packit Service a31ea6
            res = 0;
Packit Service a31ea6
        else {
Packit Service a31ea6
            fprintf(stderr, "Failed to parse '%s' %lu\n", filename,
Packit Service a31ea6
                    (unsigned long) limit);
Packit Service a31ea6
            res = 1;
Packit Service a31ea6
        }
Packit Service a31ea6
    } else {
Packit Service a31ea6
        if (fail) {
Packit Service a31ea6
            fprintf(stderr, "Failed to get failure for '%s' %lu\n",
Packit Service a31ea6
                    filename, (unsigned long) limit);
Packit Service a31ea6
            res = 1;
Packit Service a31ea6
        } else
Packit Service a31ea6
            res = 0;
Packit Service a31ea6
    }
Packit Service a31ea6
    ctxt->sax = old_sax;
Packit Service a31ea6
    xmlFreeParserCtxt(ctxt);
Packit Service a31ea6
Packit Service a31ea6
    return(res);
Packit Service a31ea6
}
Packit Service a31ea6
#ifdef LIBXML_READER_ENABLED
Packit Service a31ea6
/**
Packit Service a31ea6
 * readerTest:
Packit Service a31ea6
 * @filename: the file to parse
Packit Service a31ea6
 * @max_size: size of the limit to test
Packit Service a31ea6
 * @options: parsing options
Packit Service a31ea6
 * @fail: should a failure be reported
Packit Service a31ea6
 *
Packit Service a31ea6
 * Parse a memory generated file using the xmlReader
Packit Service a31ea6
 *
Packit Service a31ea6
 * Returns 0 in case of success, an error code otherwise
Packit Service a31ea6
 */
Packit Service a31ea6
static int
Packit Service a31ea6
readerTest(const char *filename, size_t limit, int options, int fail) {
Packit Service a31ea6
    xmlTextReaderPtr reader;
Packit Service a31ea6
    int res = 0;
Packit Service a31ea6
    int ret;
Packit Service a31ea6
Packit Service a31ea6
    nb_tests++;
Packit Service a31ea6
Packit Service a31ea6
    maxlen = limit;
Packit Service a31ea6
    reader = xmlReaderForFile(filename , NULL, options);
Packit Service a31ea6
    if (reader == NULL) {
Packit Service a31ea6
        fprintf(stderr, "Failed to open '%s' test\n", filename);
Packit Service a31ea6
	return(1);
Packit Service a31ea6
    }
Packit Service a31ea6
    ret = xmlTextReaderRead(reader);
Packit Service a31ea6
    while (ret == 1) {
Packit Service a31ea6
        ret = xmlTextReaderRead(reader);
Packit Service a31ea6
    }
Packit Service a31ea6
    if (ret != 0) {
Packit Service a31ea6
        if (fail)
Packit Service a31ea6
            res = 0;
Packit Service a31ea6
        else {
Packit Service a31ea6
            if (strncmp(filename, "crazy:", 6) == 0)
Packit Service a31ea6
                fprintf(stderr, "Failed to parse '%s' %u\n",
Packit Service a31ea6
                        filename, crazy_indx);
Packit Service a31ea6
            else
Packit Service a31ea6
                fprintf(stderr, "Failed to parse '%s' %lu\n",
Packit Service a31ea6
                        filename, (unsigned long) limit);
Packit Service a31ea6
            res = 1;
Packit Service a31ea6
        }
Packit Service a31ea6
    } else {
Packit Service a31ea6
        if (fail) {
Packit Service a31ea6
            if (strncmp(filename, "crazy:", 6) == 0)
Packit Service a31ea6
                fprintf(stderr, "Failed to get failure for '%s' %u\n",
Packit Service a31ea6
                        filename, crazy_indx);
Packit Service a31ea6
            else
Packit Service a31ea6
                fprintf(stderr, "Failed to get failure for '%s' %lu\n",
Packit Service a31ea6
                        filename, (unsigned long) limit);
Packit Service a31ea6
            res = 1;
Packit Service a31ea6
        } else
Packit Service a31ea6
            res = 0;
Packit Service a31ea6
    }
Packit Service a31ea6
    if (timeout)
Packit Service a31ea6
        res = 1;
Packit Service a31ea6
    xmlFreeTextReader(reader);
Packit Service a31ea6
Packit Service a31ea6
    return(res);
Packit Service a31ea6
}
Packit Service a31ea6
#endif
Packit Service a31ea6
Packit Service a31ea6
/************************************************************************
Packit Service a31ea6
 *									*
Packit Service a31ea6
 *			Tests descriptions				*
Packit Service a31ea6
 *									*
Packit Service a31ea6
 ************************************************************************/
Packit Service a31ea6
Packit Service a31ea6
typedef int (*functest) (const char *filename, size_t limit, int options,
Packit Service a31ea6
                         int fail);
Packit Service a31ea6
Packit Service a31ea6
typedef struct limitDesc limitDesc;
Packit Service a31ea6
typedef limitDesc *limitDescPtr;
Packit Service a31ea6
struct limitDesc {
Packit Service a31ea6
    const char *name; /* the huge generator name */
Packit Service a31ea6
    size_t limit;     /* the limit to test */
Packit Service a31ea6
    int options;      /* extra parser options */
Packit Service a31ea6
    int fail;         /* whether the test should fail */
Packit Service a31ea6
};
Packit Service a31ea6
Packit Service a31ea6
static limitDesc limitDescriptions[] = {
Packit Service a31ea6
    /* max length of a text node in content */
Packit Service a31ea6
    {"huge:textNode", XML_MAX_TEXT_LENGTH - CHUNK, 0, 0},
Packit Service a31ea6
    {"huge:textNode", XML_MAX_TEXT_LENGTH + CHUNK, 0, 1},
Packit Service a31ea6
    {"huge:textNode", XML_MAX_TEXT_LENGTH + CHUNK, XML_PARSE_HUGE, 0},
Packit Service a31ea6
    /* max length of a text node in content */
Packit Service a31ea6
    {"huge:attrNode", XML_MAX_TEXT_LENGTH - CHUNK, 0, 0},
Packit Service a31ea6
    {"huge:attrNode", XML_MAX_TEXT_LENGTH + CHUNK, 0, 1},
Packit Service a31ea6
    {"huge:attrNode", XML_MAX_TEXT_LENGTH + CHUNK, XML_PARSE_HUGE, 0},
Packit Service a31ea6
    /* max length of a comment node */
Packit Service a31ea6
    {"huge:commentNode", XML_MAX_TEXT_LENGTH - CHUNK, 0, 0},
Packit Service a31ea6
    {"huge:commentNode", XML_MAX_TEXT_LENGTH + CHUNK, 0, 1},
Packit Service a31ea6
    {"huge:commentNode", XML_MAX_TEXT_LENGTH + CHUNK, XML_PARSE_HUGE, 0},
Packit Service a31ea6
    /* max length of a PI node */
Packit Service a31ea6
    {"huge:piNode", XML_MAX_TEXT_LENGTH - CHUNK, 0, 0},
Packit Service a31ea6
    {"huge:piNode", XML_MAX_TEXT_LENGTH + CHUNK, 0, 1},
Packit Service a31ea6
    {"huge:piNode", XML_MAX_TEXT_LENGTH + CHUNK, XML_PARSE_HUGE, 0},
Packit Service a31ea6
};
Packit Service a31ea6
Packit Service a31ea6
typedef struct testDesc testDesc;
Packit Service a31ea6
typedef testDesc *testDescPtr;
Packit Service a31ea6
struct testDesc {
Packit Service a31ea6
    const char *desc; /* descripton of the test */
Packit Service a31ea6
    functest    func; /* function implementing the test */
Packit Service a31ea6
};
Packit Service a31ea6
Packit Service a31ea6
static
Packit Service a31ea6
testDesc testDescriptions[] = {
Packit Service a31ea6
    { "Parsing of huge files with the sax parser", saxTest},
Packit Service a31ea6
/*    { "Parsing of huge files with the tree parser", treeTest}, */
Packit Service a31ea6
#ifdef LIBXML_READER_ENABLED
Packit Service a31ea6
    { "Parsing of huge files with the reader", readerTest},
Packit Service a31ea6
#endif
Packit Service a31ea6
    {NULL, NULL}
Packit Service a31ea6
};
Packit Service a31ea6
Packit Service a31ea6
typedef struct testException testException;
Packit Service a31ea6
typedef testException *testExceptionPtr;
Packit Service a31ea6
struct testException {
Packit Service a31ea6
    unsigned int test;  /* the parser test number */
Packit Service a31ea6
    unsigned int limit; /* the limit test number */
Packit Service a31ea6
    int fail;           /* new fail value or -1*/
Packit Service a31ea6
    size_t size;        /* new limit value or 0 */
Packit Service a31ea6
};
Packit Service a31ea6
Packit Service a31ea6
static
Packit Service a31ea6
testException testExceptions[] = {
Packit Service a31ea6
    /* the SAX parser doesn't hit a limit of XML_MAX_TEXT_LENGTH text nodes */
Packit Service a31ea6
    { 0, 1, 0, 0},
Packit Service a31ea6
};
Packit Service a31ea6
Packit Service a31ea6
static int
Packit Service a31ea6
launchTests(testDescPtr tst, unsigned int test) {
Packit Service a31ea6
    int res = 0, err = 0;
Packit Service a31ea6
    unsigned int i, j;
Packit Service a31ea6
    size_t limit;
Packit Service a31ea6
    int fail;
Packit Service a31ea6
Packit Service a31ea6
    if (tst == NULL) return(-1);
Packit Service a31ea6
Packit Service a31ea6
    for (i = 0;i < sizeof(limitDescriptions)/sizeof(limitDescriptions[0]);i++) {
Packit Service a31ea6
        limit = limitDescriptions[i].limit;
Packit Service a31ea6
        fail = limitDescriptions[i].fail;
Packit Service a31ea6
        /*
Packit Service a31ea6
         * Handle exceptions if any
Packit Service a31ea6
         */
Packit Service a31ea6
        for (j = 0;j < sizeof(testExceptions)/sizeof(testExceptions[0]);j++) {
Packit Service a31ea6
            if ((testExceptions[j].test == test) &&
Packit Service a31ea6
                (testExceptions[j].limit == i)) {
Packit Service a31ea6
                if (testExceptions[j].fail != -1)
Packit Service a31ea6
                    fail = testExceptions[j].fail;
Packit Service a31ea6
                if (testExceptions[j].size != 0)
Packit Service a31ea6
                    limit = testExceptions[j].size;
Packit Service a31ea6
                break;
Packit Service a31ea6
            }
Packit Service a31ea6
        }
Packit Service a31ea6
        res = tst->func(limitDescriptions[i].name, limit,
Packit Service a31ea6
                        limitDescriptions[i].options, fail);
Packit Service a31ea6
        if (res != 0) {
Packit Service a31ea6
            nb_errors++;
Packit Service a31ea6
            err++;
Packit Service a31ea6
        }
Packit Service a31ea6
    }
Packit Service a31ea6
    return(err);
Packit Service a31ea6
}
Packit Service a31ea6
Packit Service a31ea6
Packit Service a31ea6
static int
Packit Service a31ea6
runtest(unsigned int i) {
Packit Service a31ea6
    int ret = 0, res;
Packit Service a31ea6
    int old_errors, old_tests, old_leaks;
Packit Service a31ea6
Packit Service a31ea6
    old_errors = nb_errors;
Packit Service a31ea6
    old_tests = nb_tests;
Packit Service a31ea6
    old_leaks = nb_leaks;
Packit Service a31ea6
    if ((tests_quiet == 0) && (testDescriptions[i].desc != NULL))
Packit Service a31ea6
	printf("## %s\n", testDescriptions[i].desc);
Packit Service a31ea6
    res = launchTests(&testDescriptions[i], i);
Packit Service a31ea6
    if (res != 0)
Packit Service a31ea6
	ret++;
Packit Service a31ea6
    if (verbose) {
Packit Service a31ea6
	if ((nb_errors == old_errors) && (nb_leaks == old_leaks))
Packit Service a31ea6
	    printf("Ran %d tests, no errors\n", nb_tests - old_tests);
Packit Service a31ea6
	else
Packit Service a31ea6
	    printf("Ran %d tests, %d errors, %d leaks\n",
Packit Service a31ea6
		   nb_tests - old_tests,
Packit Service a31ea6
		   nb_errors - old_errors,
Packit Service a31ea6
		   nb_leaks - old_leaks);
Packit Service a31ea6
    }
Packit Service a31ea6
    return(ret);
Packit Service a31ea6
}
Packit Service a31ea6
Packit Service a31ea6
static int
Packit Service a31ea6
launchCrazySAX(unsigned int test, int fail) {
Packit Service a31ea6
    int res = 0, err = 0;
Packit Service a31ea6
Packit Service a31ea6
    crazy_indx = test;
Packit Service a31ea6
Packit Service a31ea6
    res = saxTest("crazy::test", XML_MAX_LOOKUP_LIMIT - CHUNK, 0, fail);
Packit Service a31ea6
    if (res != 0) {
Packit Service a31ea6
        nb_errors++;
Packit Service a31ea6
        err++;
Packit Service a31ea6
    }
Packit Service a31ea6
    if (tests_quiet == 0)
Packit Service a31ea6
        fprintf(stderr, "%c", crazy[test]);
Packit Service a31ea6
Packit Service a31ea6
    return(err);
Packit Service a31ea6
}
Packit Service a31ea6
Packit Service a31ea6
#ifdef LIBXML_READER_ENABLED
Packit Service a31ea6
static int
Packit Service a31ea6
launchCrazy(unsigned int test, int fail) {
Packit Service a31ea6
    int res = 0, err = 0;
Packit Service a31ea6
Packit Service a31ea6
    crazy_indx = test;
Packit Service a31ea6
Packit Service a31ea6
    res = readerTest("crazy::test", XML_MAX_LOOKUP_LIMIT - CHUNK, 0, fail);
Packit Service a31ea6
    if (res != 0) {
Packit Service a31ea6
        nb_errors++;
Packit Service a31ea6
        err++;
Packit Service a31ea6
    }
Packit Service a31ea6
    if (tests_quiet == 0)
Packit Service a31ea6
        fprintf(stderr, "%c", crazy[test]);
Packit Service a31ea6
Packit Service a31ea6
    return(err);
Packit Service a31ea6
}
Packit Service a31ea6
#endif
Packit Service a31ea6
Packit Service a31ea6
static int get_crazy_fail(int test) {
Packit Service a31ea6
    /*
Packit Service a31ea6
     * adding 1000000 of character 'a' leads to parser failure mostly
Packit Service a31ea6
     * everywhere except in those special spots. Need to be updated
Packit Service a31ea6
     * each time crazy is updated
Packit Service a31ea6
     */
Packit Service a31ea6
    int fail = 1;
Packit Service a31ea6
    if ((test == 44) || /* PI in Misc */
Packit Service a31ea6
        ((test >= 50) && (test <= 55)) || /* Comment in Misc */
Packit Service a31ea6
        (test == 79) || /* PI in DTD */
Packit Service a31ea6
        ((test >= 85) && (test <= 90)) || /* Comment in DTD */
Packit Service a31ea6
        (test == 154) || /* PI in Misc */
Packit Service a31ea6
        ((test >= 160) && (test <= 165)) || /* Comment in Misc */
Packit Service a31ea6
        ((test >= 178) && (test <= 181)) || /* attribute value */
Packit Service a31ea6
        (test == 183) || /* Text */
Packit Service a31ea6
        (test == 189) || /* PI in Content */
Packit Service a31ea6
        (test == 191) || /* Text */
Packit Service a31ea6
        ((test >= 195) && (test <= 200)) || /* Comment in Content */
Packit Service a31ea6
        ((test >= 203) && (test <= 206)) || /* Text */
Packit Service a31ea6
        (test == 215) || (test == 216) || /* in CDATA */
Packit Service a31ea6
        (test == 219) || /* Text */
Packit Service a31ea6
        (test == 231) || /* PI in Misc */
Packit Service a31ea6
        ((test >= 237) && (test <= 242))) /* Comment in Misc */
Packit Service a31ea6
        fail = 0;
Packit Service a31ea6
    return(fail);
Packit Service a31ea6
}
Packit Service a31ea6
Packit Service a31ea6
static int
Packit Service a31ea6
runcrazy(void) {
Packit Service a31ea6
    int ret = 0, res = 0;
Packit Service a31ea6
    int old_errors, old_tests, old_leaks;
Packit Service a31ea6
    unsigned int i;
Packit Service a31ea6
Packit Service a31ea6
    old_errors = nb_errors;
Packit Service a31ea6
    old_tests = nb_tests;
Packit Service a31ea6
    old_leaks = nb_leaks;
Packit Service a31ea6
Packit Service a31ea6
#ifdef LIBXML_READER_ENABLED
Packit Service a31ea6
    if (tests_quiet == 0) {
Packit Service a31ea6
	printf("## Crazy tests on reader\n");
Packit Service a31ea6
    }
Packit Service a31ea6
    for (i = 0;i < strlen(crazy);i++) {
Packit Service a31ea6
        res += launchCrazy(i, get_crazy_fail(i));
Packit Service a31ea6
        if (res != 0)
Packit Service a31ea6
            ret++;
Packit Service a31ea6
    }
Packit Service a31ea6
#endif
Packit Service a31ea6
Packit Service a31ea6
    if (tests_quiet == 0) {
Packit Service a31ea6
	printf("\n## Crazy tests on SAX\n");
Packit Service a31ea6
    }
Packit Service a31ea6
    for (i = 0;i < strlen(crazy);i++) {
Packit Service a31ea6
        res += launchCrazySAX(i, get_crazy_fail(i));
Packit Service a31ea6
        if (res != 0)
Packit Service a31ea6
            ret++;
Packit Service a31ea6
    }
Packit Service a31ea6
    if (tests_quiet == 0)
Packit Service a31ea6
        fprintf(stderr, "\n");
Packit Service a31ea6
    if (verbose) {
Packit Service a31ea6
	if ((nb_errors == old_errors) && (nb_leaks == old_leaks))
Packit Service a31ea6
	    printf("Ran %d tests, no errors\n", nb_tests - old_tests);
Packit Service a31ea6
	else
Packit Service a31ea6
	    printf("Ran %d tests, %d errors, %d leaks\n",
Packit Service a31ea6
		   nb_tests - old_tests,
Packit Service a31ea6
		   nb_errors - old_errors,
Packit Service a31ea6
		   nb_leaks - old_leaks);
Packit Service a31ea6
    }
Packit Service a31ea6
    return(ret);
Packit Service a31ea6
}
Packit Service a31ea6
Packit Service a31ea6
Packit Service a31ea6
int
Packit Service a31ea6
main(int argc ATTRIBUTE_UNUSED, char **argv ATTRIBUTE_UNUSED) {
Packit Service a31ea6
    int i, a, ret = 0;
Packit Service a31ea6
    int subset = 0;
Packit Service a31ea6
Packit Service a31ea6
    fillFilling();
Packit Service a31ea6
    initializeLibxml2();
Packit Service a31ea6
Packit Service a31ea6
    for (a = 1; a < argc;a++) {
Packit Service a31ea6
        if (!strcmp(argv[a], "-v"))
Packit Service a31ea6
	    verbose = 1;
Packit Service a31ea6
        else if (!strcmp(argv[a], "-quiet"))
Packit Service a31ea6
	    tests_quiet = 1;
Packit Service a31ea6
        else if (!strcmp(argv[a], "-crazy"))
Packit Service a31ea6
	    subset = 1;
Packit Service a31ea6
    }
Packit Service a31ea6
    if (subset == 0) {
Packit Service a31ea6
	for (i = 0; testDescriptions[i].func != NULL; i++) {
Packit Service a31ea6
	    ret += runtest(i);
Packit Service a31ea6
	}
Packit Service a31ea6
    }
Packit Service a31ea6
    ret += runcrazy();
Packit Service a31ea6
    if ((nb_errors == 0) && (nb_leaks == 0)) {
Packit Service a31ea6
        ret = 0;
Packit Service a31ea6
	printf("Total %d tests, no errors\n",
Packit Service a31ea6
	       nb_tests);
Packit Service a31ea6
    } else {
Packit Service a31ea6
        ret = 1;
Packit Service a31ea6
	printf("Total %d tests, %d errors, %d leaks\n",
Packit Service a31ea6
	       nb_tests, nb_errors, nb_leaks);
Packit Service a31ea6
    }
Packit Service a31ea6
    xmlCleanupParser();
Packit Service a31ea6
    xmlMemoryDump();
Packit Service a31ea6
Packit Service a31ea6
    return(ret);
Packit Service a31ea6
}