/* * testparser.c: Additional parser tests * * See Copyright for the status of this software. */ #include "libxml.h" #include #include #include #include #include static int testStandaloneWithEncoding(void) { xmlDocPtr doc; const char *str = "\n" "\n"; int err = 0; xmlResetLastError(); doc = xmlReadDoc(BAD_CAST str, NULL, "UTF-8", 0); if (doc == NULL) { fprintf(stderr, "xmlReadDoc failed\n"); err = 1; } xmlFreeDoc(doc); return err; } static int testUnsupportedEncoding(void) { xmlDocPtr doc; const xmlError *error; int err = 0; xmlResetLastError(); doc = xmlReadDoc(BAD_CAST "", NULL, "#unsupported", XML_PARSE_NOWARNING); if (doc == NULL) { fprintf(stderr, "xmlReadDoc failed with unsupported encoding\n"); err = 1; } xmlFreeDoc(doc); error = xmlGetLastError(); if (error->code != XML_ERR_UNSUPPORTED_ENCODING || error->level != XML_ERR_WARNING || strcmp(error->message, "Unsupported encoding: #unsupported\n") != 0) { fprintf(stderr, "xmlReadDoc failed to raise correct error\n"); err = 1; } return err; } static int testNodeGetContent(void) { xmlDocPtr doc; xmlChar *content; int err = 0; doc = xmlReadDoc(BAD_CAST "", NULL, NULL, 0); xmlAddChild(doc->children, xmlNewReference(doc, BAD_CAST "lt")); content = xmlNodeGetContent((xmlNodePtr) doc); if (strcmp((char *) content, "<") != 0) { fprintf(stderr, "xmlNodeGetContent failed\n"); err = 1; } xmlFree(content); xmlFreeDoc(doc); return err; } #ifdef LIBXML_SAX1_ENABLED static int testBalancedChunk(void) { xmlNodePtr list; xmlNodePtr elem; int ret; int err = 0; ret = xmlParseBalancedChunkMemory(NULL, NULL, NULL, 0, BAD_CAST "start abc end", &list); if ((ret != XML_ERR_OK) || (list == NULL) || ((elem = list->next) == NULL) || (elem->type != XML_ELEMENT_NODE) || (elem->nsDef == NULL) || (!xmlStrEqual(elem->nsDef->href, XML_XML_NAMESPACE))) { fprintf(stderr, "xmlParseBalancedChunkMemory failed\n"); err = 1; } xmlFreeNodeList(list); return(err); } #endif #ifdef LIBXML_PUSH_ENABLED static int testHugePush(void) { xmlParserCtxtPtr ctxt; int err, i; ctxt = xmlCreatePushParserCtxt(NULL, NULL, NULL, 0, NULL); /* * Push parse a document larger than XML_MAX_LOOKUP_LIMIT * (10,000,000 bytes). This mainly tests whether shrinking the * buffer works when push parsing. */ xmlParseChunk(ctxt, "", 5, 0); for (i = 0; i < 1000000; i++) xmlParseChunk(ctxt, "text", 17, 0); xmlParseChunk(ctxt, "", 6, 1); err = ctxt->wellFormed ? 0 : 1; xmlFreeDoc(ctxt->myDoc); xmlFreeParserCtxt(ctxt); return err; } static int testHugeEncodedChunk(void) { xmlBufferPtr buf; xmlChar *chunk; xmlParserCtxtPtr ctxt; int err, i; /* * Test the push parser with a built-in encoding handler like ISO-8859-1 * and a chunk larger than the initial decoded buffer (currently 4 KB). */ buf = xmlBufferCreate(); xmlBufferCat(buf, BAD_CAST "\n"); xmlBufferCat(buf, BAD_CAST ""); chunk = xmlBufferDetach(buf); xmlBufferFree(buf); ctxt = xmlCreatePushParserCtxt(NULL, NULL, NULL, 0, NULL); xmlParseChunk(ctxt, (char *) chunk, xmlStrlen(chunk), 0); xmlParseChunk(ctxt, NULL, 0, 1); err = ctxt->wellFormed ? 0 : 1; xmlFreeDoc(ctxt->myDoc); xmlFreeParserCtxt(ctxt); xmlFree(chunk); return err; } #ifdef LIBXML_HTML_ENABLED static int testHtmlPushWithEncoding(void) { htmlParserCtxtPtr ctxt; htmlDocPtr doc; htmlNodePtr node; int err = 0; ctxt = htmlCreatePushParserCtxt(NULL, NULL, NULL, 0, NULL, XML_CHAR_ENCODING_UTF8); htmlParseChunk(ctxt, "-\xC3\xA4-", 4, 1); doc = ctxt->myDoc; if (!xmlStrEqual(doc->encoding, BAD_CAST "UTF-8")) { fprintf(stderr, "testHtmlPushWithEncoding failed\n"); err = 1; } node = xmlDocGetRootElement(doc)->children->children->children; if (!xmlStrEqual(node->content, BAD_CAST "-\xC3\xA4-")) { fprintf(stderr, "testHtmlPushWithEncoding failed\n"); err = 1; } xmlFreeDoc(doc); htmlFreeParserCtxt(ctxt); return err; } #endif #endif #ifdef LIBXML_READER_ENABLED static int testReaderEncoding(void) { xmlBuffer *buf; xmlTextReader *reader; xmlChar *xml; const xmlChar *encoding; int err = 0; int i; buf = xmlBufferCreate(); xmlBufferCCat(buf, "\n"); xmlBufferCCat(buf, ""); for (i = 0; i < 8192; i++) xmlBufferCCat(buf, "x"); xmlBufferCCat(buf, ""); xml = xmlBufferDetach(buf); xmlBufferFree(buf); reader = xmlReaderForDoc(BAD_CAST xml, NULL, NULL, 0); xmlTextReaderRead(reader); encoding = xmlTextReaderConstEncoding(reader); if (!xmlStrEqual(encoding, BAD_CAST "ISO-8859-1")) { fprintf(stderr, "testReaderEncoding failed\n"); err = 1; } xmlFreeTextReader(reader); xmlFree(xml); return err; } static int testReaderContent(void) { xmlTextReader *reader; const xmlChar *xml = BAD_CAST "xyz"; xmlChar *string; int err = 0; reader = xmlReaderForDoc(xml, NULL, NULL, 0); xmlTextReaderRead(reader); string = xmlTextReaderReadOuterXml(reader); if (!xmlStrEqual(string, xml)) { fprintf(stderr, "xmlTextReaderReadOuterXml failed\n"); err = 1; } xmlFree(string); string = xmlTextReaderReadInnerXml(reader); if (!xmlStrEqual(string, BAD_CAST "xyz")) { fprintf(stderr, "xmlTextReaderReadInnerXml failed\n"); err = 1; } xmlFree(string); string = xmlTextReaderReadString(reader); if (!xmlStrEqual(string, BAD_CAST "xyz")) { fprintf(stderr, "xmlTextReaderReadString failed\n"); err = 1; } xmlFree(string); xmlFreeTextReader(reader); return err; } #ifdef LIBXML_XINCLUDE_ENABLED typedef struct { char *message; int code; } testReaderErrorCtxt; static void testReaderError(void *arg, const char *msg, xmlParserSeverities severity ATTRIBUTE_UNUSED, xmlTextReaderLocatorPtr locator ATTRIBUTE_UNUSED) { testReaderErrorCtxt *ctxt = arg; if (ctxt->message != NULL) xmlFree(ctxt->message); ctxt->message = xmlMemStrdup(msg); } static void testStructuredReaderError(void *arg, const xmlError *error) { testReaderErrorCtxt *ctxt = arg; if (ctxt->message != NULL) xmlFree(ctxt->message); ctxt->message = xmlMemStrdup(error->message); ctxt->code = error->code; } static int testReaderXIncludeError(void) { /* * Test whether XInclude errors are reported to the custom error * handler of a reader. */ const char *doc = "\n" " \n" "\n"; xmlTextReader *reader; testReaderErrorCtxt errorCtxt; int err = 0; reader = xmlReaderForDoc(BAD_CAST doc, NULL, NULL, XML_PARSE_XINCLUDE); xmlTextReaderSetErrorHandler(reader, testReaderError, &errorCtxt); errorCtxt.message = NULL; errorCtxt.code = 0; while (xmlTextReaderRead(reader) > 0) ; if (errorCtxt.message == NULL || strstr(errorCtxt.message, "href or xpointer") == NULL) { fprintf(stderr, "xmlTextReaderSetErrorHandler failed\n"); err = 1; } xmlFree(errorCtxt.message); xmlFreeTextReader(reader); reader = xmlReaderForDoc(BAD_CAST doc, NULL, NULL, XML_PARSE_XINCLUDE); xmlTextReaderSetStructuredErrorHandler(reader, testStructuredReaderError, &errorCtxt); errorCtxt.message = NULL; errorCtxt.code = 0; while (xmlTextReaderRead(reader) > 0) ; if (errorCtxt.code != XML_XINCLUDE_NO_HREF || errorCtxt.message == NULL || strstr(errorCtxt.message, "href or xpointer") == NULL) { fprintf(stderr, "xmlTextReaderSetStructuredErrorHandler failed\n"); err = 1; } xmlFree(errorCtxt.message); xmlFreeTextReader(reader); return err; } #endif #endif #ifdef LIBXML_WRITER_ENABLED static int testWriterIOWrite(void *ctxt, const char *data, int len) { (void) ctxt; (void) data; return len; } static int testWriterIOClose(void *ctxt) { (void) ctxt; return XML_IO_ENAMETOOLONG; } static int testWriterClose(void){ xmlOutputBufferPtr out; xmlTextWriterPtr writer; int err = 0; int result; out = xmlOutputBufferCreateIO(testWriterIOWrite, testWriterIOClose, NULL, NULL); writer = xmlNewTextWriter(out); xmlTextWriterStartDocument(writer, "1.0", "UTF-8", NULL); xmlTextWriterStartElement(writer, BAD_CAST "elem"); xmlTextWriterEndElement(writer); xmlTextWriterEndDocument(writer); result = xmlTextWriterClose(writer); if (result != XML_IO_ENAMETOOLONG) { fprintf(stderr, "xmlTextWriterClose reported wrong error %d\n", result); err = 1; } xmlFreeTextWriter(writer); return err; } #endif int main(void) { int err = 0; err |= testStandaloneWithEncoding(); err |= testUnsupportedEncoding(); err |= testNodeGetContent(); #ifdef LIBXML_SAX1_ENABLED err |= testBalancedChunk(); #endif #ifdef LIBXML_PUSH_ENABLED err |= testHugePush(); err |= testHugeEncodedChunk(); #ifdef LIBXML_HTML_ENABLED err |= testHtmlPushWithEncoding(); #endif #endif #ifdef LIBXML_READER_ENABLED err |= testReaderEncoding(); err |= testReaderContent(); #ifdef LIBXML_XINCLUDE_ENABLED err |= testReaderXIncludeError(); #endif #endif #ifdef LIBXML_WRITER_ENABLED err |= testWriterClose(); #endif return err; }