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