From 0c1d871e4c5e46a2945cccb2ce765f9be2fe01fb Mon Sep 17 00:00:00 2001 From: Mike Hommey Date: Sun, 1 Mar 2009 10:54:34 +0100 Subject: Import upstream version 2.7.1 --- ChangeLog | 35 ++++++ HTMLtree.c | 7 +- Makefile.am | 4 +- Makefile.in | 4 +- NEWS | 35 ++++++ configure | 2 +- configure.in | 2 +- doc/libxml2.xsa | 61 +++++----- doc/news.html | 7 +- doc/xml.html | 9 ++ gentest.py | 1 + include/libxml/xmlversion.h | 8 +- libxml2.spec | 6 +- parser.c | 2 +- python/libxml.c | 147 ++++++----------------- python/setup.py | 2 +- python/tests/Makefile.am | 3 +- python/tests/Makefile.in | 3 +- python/tests/xpathleak.py | 53 +++++++++ runxmlconf.c | 8 +- schematron.c | 2 +- testapi.c | 4 +- tree.c | 13 ++- trionan.c | 8 +- xmlIO.c | 69 +++++++++-- xmlsave.c | 279 +++++++++++++++++++++++++++++++------------- xpath.c | 40 ++++--- 27 files changed, 530 insertions(+), 284 deletions(-) create mode 100755 python/tests/xpathleak.py diff --git a/ChangeLog b/ChangeLog index 1f976e8..2ef2cc7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,38 @@ +Mon Sep 1 16:49:05 CEST 2008 Daniel Veillard + + * doc/xml.html doc/news.html configure.in python/setup.py NEWS: + prepare release of 2.7.1 + +Mon Sep 1 15:35:13 CEST 2008 Daniel Veillard + + * schematron.c xpath.c: applied a couple of patches from Martin + avoiding some leaks, fixinq QName checks in XPath, XPath debugging + and schematron code cleanups. + * python/tests/Makefile.am python/tests/xpathleak.py: add the + specific regression tests, just tweak it to avoid output by default + +Mon Sep 1 15:02:05 CEST 2008 Daniel Veillard + + * trionan.c: Borland C fix from Moritz Both + * testapi.c: regenerate, workaround a problem for buffer testing + * xmlIO.c HTMLtree.c: new internal entry point to hide even better + xmlAllocOutputBufferInternal + * tree.c: harden the code around buffer allocation schemes + * parser.c: restore the warning when namespace names are not absolute + URIs + * runxmlconf.c: continue regression tests if we get the expected + number of errors + * Makefile.am: run the python tests on make check + * xmlsave.c: handle the HTML documents and trees + * python/libxml.c: convert python serialization to the xmlSave APIs + and avoid some horrible hacks + +Sat Aug 30 16:58:40 CEST 2008 Daniel Veillard + + * configure.in, doc/*: preparing 2.7.0 release + * tree.c: remove some testing traces + * parser.c xmlIO.c xmlschemas.c: remove some warnings + Sat Aug 30 14:50:16 CEST 2008 Daniel Veillard * include/libxml/tree.h tree.c: make a new kind of buffer where diff --git a/HTMLtree.c b/HTMLtree.c index e79d118..37999f7 100644 --- a/HTMLtree.c +++ b/HTMLtree.c @@ -316,6 +316,11 @@ htmlIsBooleanAttr(const xmlChar *name) } #ifdef LIBXML_OUTPUT_ENABLED +/* + * private routine exported from xmlIO.c + */ +xmlOutputBufferPtr +xmlAllocOutputBufferInternal(xmlCharEncodingHandlerPtr encoder); /************************************************************************ * * * Output error handlers * @@ -566,7 +571,7 @@ htmlDocDumpMemoryFormat(xmlDocPtr cur, xmlChar**mem, int *size, int format) { if (handler == NULL) handler = xmlFindCharEncodingHandler("ascii"); - buf = xmlAllocOutputBuffer(handler); + buf = xmlAllocOutputBufferInternal(handler); if (buf == NULL) { *mem = NULL; *size = 0; diff --git a/Makefile.am b/Makefile.am index de57c46..800a766 100644 --- a/Makefile.am +++ b/Makefile.am @@ -157,7 +157,7 @@ rebuild_testapi: # that one is just to make sure it is rebuilt if missing # but adding the dependances generate mess -testapi.c: +testapi.c: $(srcdir)/gentest.py -@(if [ "$(PYTHON)" != "" ] ; then \ $(PYTHON) $(srcdir)/gentest.py $(srcdir) ; fi ) @@ -178,6 +178,8 @@ runxmlconf_LDADD= $(LDADDS) runtests: $(CHECKER) ./runtest$(EXEEXT) && $(CHECKER) ./testrecurse$(EXEEXT) &&$(CHECKER) ./testapi$(EXEEXT) && $(CHECKER) ./testchar$(EXEEXT)&& $(CHECKER) ./testdict$(EXEEXT) && $(CHECKER) ./runxmlconf$(EXEEXT) + @(if [ "@PYTHON_SUBDIR@" != "" ] ; then cd python ; \ + $(MAKE) MAKEFLAGS+=--silent tests ; fi) check: all runtests diff --git a/Makefile.in b/Makefile.in index d986d7b..ddcfd91 100644 --- a/Makefile.in +++ b/Makefile.in @@ -1555,7 +1555,7 @@ rebuild_testapi: # that one is just to make sure it is rebuilt if missing # but adding the dependances generate mess -testapi.c: +testapi.c: $(srcdir)/gentest.py -@(if [ "$(PYTHON)" != "" ] ; then \ $(PYTHON) $(srcdir)/gentest.py $(srcdir) ; fi ) @@ -1566,6 +1566,8 @@ testapi.c: runtests: $(CHECKER) ./runtest$(EXEEXT) && $(CHECKER) ./testrecurse$(EXEEXT) &&$(CHECKER) ./testapi$(EXEEXT) && $(CHECKER) ./testchar$(EXEEXT)&& $(CHECKER) ./testdict$(EXEEXT) && $(CHECKER) ./runxmlconf$(EXEEXT) + @(if [ "@PYTHON_SUBDIR@" != "" ] ; then cd python ; \ + $(MAKE) MAKEFLAGS+=--silent tests ; fi) check: all runtests diff --git a/NEWS b/NEWS index 2d6a794..8c34320 100644 --- a/NEWS +++ b/NEWS @@ -15,6 +15,41 @@ ChangeLog.html to the SVN at http://svn.gnome.org/viewcvs/libxml2/trunk/ code base.Here is the list of public releases: +2.7.1: Sep 1 2008: + - Portability fix: Borland C fix (Moritz Both) + - Bug fixes: python serialization wrappers, XPath QName corner + case handking and leaks (Martin) + - Improvement: extend the xmlSave to handle HTML documents and trees + - Cleanup: python serialization wrappers + + +2.7.0: Aug 30 2008: + - Documentation: switch ChangeLog to UTF-8, improve mutithreads and + xmlParserCleanup docs + - Portability fixes: Older Win32 platforms (Rob Richards), MSVC + porting fix (Rob Richards), Mac OS X regression tests (Sven Herzberg), + non GNUCC builds (Rob Richards), compilation on Haiku (Andreas Färber) + + - Bug fixes: various realloc problems (Ashwin), potential double-free + (Ashwin), regexp crash, icrash with invalid whitespace facets (Rob + Richards), pattern fix when streaming (William Brack), various XML + parsing and validation fixes based on the W3C regression tests, reader + tree skipping function fix (Ashwin), Schemas regexps escaping fix + (Volker Grabsch), handling of entity push errors (Ashwin), fix a slowdown + when encoder cant serialize characters on output + - Code cleanup: compilation fix without the reader, without the output + (Robert Schwebel), python whitespace (Martin), many space/tabs cleanups, + serious cleanup of the entity handling code + - Improvement: switch parser to XML-1.0 5th edition, add parsing flags + for old versions, switch URI parsing to RFC 3986, + add xmlSchemaValidCtxtGetParserCtxt (Holger Kaelberer), + new hashing functions for dictionnaries (based on Stefan Behnel work), + improve handling of misplaced html/head/body in HTML parser, better + regression test tools and code coverage display, better algorithms + to detect various versions of the billion laughts attacks, make + arbitrary parser limits avoidable as a parser option + + 2.6.32: Apr 8 2008: - Documentation: returning heap memory to kernel (Wolfram Sang), trying to clarify xmlCleanupParser() use, xmlXPathContext improvement diff --git a/configure b/configure index 5360aa8..e782bfb 100755 --- a/configure +++ b/configure @@ -2191,7 +2191,7 @@ case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac LIBXML_MAJOR_VERSION=2 LIBXML_MINOR_VERSION=7 -LIBXML_MICRO_VERSION=0 +LIBXML_MICRO_VERSION=1 LIBXML_MICRO_VERSION_SUFFIX= LIBXML_VERSION=$LIBXML_MAJOR_VERSION.$LIBXML_MINOR_VERSION.$LIBXML_MICRO_VERSION$LIBXML_MICRO_VERSION_SUFFIX LIBXML_VERSION_INFO=`expr $LIBXML_MAJOR_VERSION + $LIBXML_MINOR_VERSION`:$LIBXML_MICRO_VERSION:$LIBXML_MINOR_VERSION diff --git a/configure.in b/configure.in index 65824f3..17dad0b 100644 --- a/configure.in +++ b/configure.in @@ -5,7 +5,7 @@ AC_CANONICAL_HOST LIBXML_MAJOR_VERSION=2 LIBXML_MINOR_VERSION=7 -LIBXML_MICRO_VERSION=0 +LIBXML_MICRO_VERSION=1 LIBXML_MICRO_VERSION_SUFFIX= LIBXML_VERSION=$LIBXML_MAJOR_VERSION.$LIBXML_MINOR_VERSION.$LIBXML_MICRO_VERSION$LIBXML_MICRO_VERSION_SUFFIX LIBXML_VERSION_INFO=`expr $LIBXML_MAJOR_VERSION + $LIBXML_MINOR_VERSION`:$LIBXML_MICRO_VERSION:$LIBXML_MINOR_VERSION diff --git a/doc/libxml2.xsa b/doc/libxml2.xsa index f93c298..bcb3a0e 100644 --- a/doc/libxml2.xsa +++ b/doc/libxml2.xsa @@ -8,42 +8,33 @@ libxml2 - 2.6.32 - Apr 8 2008 + 2.7.0 + Aug 30 2008 http://xmlsoft.org/ - - Documentation: returning heap memory to kernel (Wolfram Sang), - trying to clarify xmlCleanupParser() use, xmlXPathContext improvement - (Jack Jansen), improve the *Recover* functions documentation, - XmlNodeType doc link fix (Martijn Arts) - - Bug fixes: internal subset memory leak (Ashwin), avoid problem with - paths starting with // (Petr Sumbera), streaming XSD validation callback - patches (Ashwin), fix redirection on port other than 80 (William Brack), - SAX2 leak (Ashwin), XInclude fragment of own document (Chris Ryan), - regexp bug with '.' (Andrew Tosh), flush the writer at the end of the - document (Alfred Mickautsch), output I/O bug fix (William Brack), - writer CDATA output after a text node (Alex Khesin), UTF-16 encoding - detection (William Brack), fix handling of empty CDATA nodes for Safari - team, python binding problem with namespace nodes, improve HTML parsing - (Arnold Hendriks), regexp automata build bug, memory leak fix (Vasily - Chekalkin), XSD test crash, weird system parameter entity parsing problem, - allow save to file:///X:/ windows paths, various attribute normalisation - problems, externalSubsetSplit fix (Ashwin), attribute redefinition in - the DTD (Ashwin), fix in char ref parsing check (Alex Khesin), many - out of memory handling fixes (Ashwin), XPath out of memory handling fixes - (Alvaro Herrera), various realloc problems (Ashwin), UCS4 encoding - conversion buffer size (Christian Fruth), problems with EatName - functions on memory errors, BOM handling in external parsed entities - (Mark Rowe) - - Code cleanup: fix build under VS 2008 (David Wimsey), remove useless - mutex in xmlDict (Florent Guilian), Mingw32 compilation fix (Carlo - Bramini), Win and MacOS EOL cleanups (Florent Guiliani), iconv need - a const detection (Roumen Petrov), simplify xmlSetProp (Julien Charbon), - cross compilation fixes for Mingw (Roumen Petrov), SCO Openserver build - fix (Florent Guiliani), iconv uses const on Win32 (Rob Richards), - duplicate code removal (Ashwin), missing malloc test and error reports - (Ashwin), VMS makefile fix (Tycho Hilhorst) - - improvements: better plug of schematron in the normal error handling - (Tobias Minich) + - Documentation: switch ChangeLog to UTF-8, improve mutithreads and + xmlParserCleanup docs + - Portability fixes: Older Win32 platforms (Rob Richards), MSVC + porting fix (Rob Richards), Mac OS X regression tests (Sven Herzberg), + non GNUCC builds (Rob Richards), compilation on Haiku (Andreas Färber) + + - Bug fixes: various realloc problems (Ashwin), potential double-free + (Ashwin), regexp crash, icrash with invalid whitespace facets (Rob + Richards), pattern fix when streaming (William Brack), various XML + parsing and validation fixes based on the W3C regression tests, reader + tree skipping function fix (Ashwin), Schemas regexps escaping fix + (Volker Grabsch), handling of entity push errors (Ashwin), fix a slowdown + when encoder cant serialize characters on output + - Code cleanup: compilation fix without the reader, without the output + (Robert Schwebel), python whitespace (Martin), many space/tabs cleanups, + serious cleanup of the entity handling code + - Improvement: switch parser to XML-1.0 5th edition, add parsing flags + for old versions, switch URI parsing to RFC 3986, + add xmlSchemaValidCtxtGetParserCtxt (Holger Kaelberer), + new hashing functions for dictionnaries (based on Stefan Behnel work), + improve handling of misplaced html/head/body in HTML parser, better + regression test tools and code coverage display, better algorithms + to detect various versions of the billion laughts attacks, make + arbitrary parser limits avoidable as a parser option diff --git a/doc/news.html b/doc/news.html index a4126c0..d9dd809 100644 --- a/doc/news.html +++ b/doc/news.html @@ -12,7 +12,12 @@ to help those

The change log describes the recents commits -to the SVN code base.

Here is the list of public releases:

2.7.0: Aug 30 2008

  • Documentation: switch ChangeLog to UTF-8, improve mutithreads and +to the SVN code base.

    Here is the list of public releases:

    2.7.1: Sep 1 2008

    • Portability fix: Borland C fix (Moritz Both)
    • +
    • Bug fixes: python serialization wrappers, XPath QName corner + case handking and leaks (Martin)
    • +
    • Improvement: extend the xmlSave to handle HTML documents and trees
    • +
    • Cleanup: python serialization wrappers
    • +

    2.7.0: Aug 30 2008

    • Documentation: switch ChangeLog to UTF-8, improve mutithreads and xmlParserCleanup docs
    • Portability fixes: Older Win32 platforms (Rob Richards), MSVC porting fix (Rob Richards), Mac OS X regression tests (Sven Herzberg), diff --git a/doc/xml.html b/doc/xml.html index 30398d2..9117958 100644 --- a/doc/xml.html +++ b/doc/xml.html @@ -727,6 +727,15 @@ to the SVN code base.<

      Here is the list of public releases:

      +

      2.7.1: Sep 1 2008

      +
        +
      • Portability fix: Borland C fix (Moritz Both)
      • +
      • Bug fixes: python serialization wrappers, XPath QName corner + case handking and leaks (Martin)
      • +
      • Improvement: extend the xmlSave to handle HTML documents and trees
      • +
      • Cleanup: python serialization wrappers
      • +
      +

      2.7.0: Aug 30 2008

      • Documentation: switch ChangeLog to UTF-8, improve mutithreads and diff --git a/gentest.py b/gentest.py index 17c9f59..f178620 100755 --- a/gentest.py +++ b/gentest.py @@ -260,6 +260,7 @@ extra_post_call = { "xmlParseChunk": "if (ctxt != NULL) {xmlFreeDoc(ctxt->myDoc); ctxt->myDoc = NULL;}", "xmlParseExtParsedEnt": "if (ctxt != NULL) {xmlFreeDoc(ctxt->myDoc); ctxt->myDoc = NULL;}", "xmlDOMWrapAdoptNode": "if ((node != NULL) && (node->parent == NULL)) {xmlUnlinkNode(node);xmlFreeNode(node);node = NULL;}", + "xmlBufferSetAllocationScheme": "if ((buf != NULL) && (scheme == XML_BUFFER_ALLOC_IMMUTABLE) && (buf->content != NULL) && (buf->content != static_buf_content)) { xmlFree(buf->content); buf->content = NULL;}" } modules = [] diff --git a/include/libxml/xmlversion.h b/include/libxml/xmlversion.h index e00a6e9..227a860 100644 --- a/include/libxml/xmlversion.h +++ b/include/libxml/xmlversion.h @@ -29,21 +29,21 @@ XMLPUBFUN void XMLCALL xmlCheckVersion(int version); * * the version string like "1.2.3" */ -#define LIBXML_DOTTED_VERSION "2.7.0" +#define LIBXML_DOTTED_VERSION "2.7.1" /** * LIBXML_VERSION: * * the version number: 1.2.3 value is 10203 */ -#define LIBXML_VERSION 20700 +#define LIBXML_VERSION 20701 /** * LIBXML_VERSION_STRING: * * the version number string, 1.2.3 value is "10203" */ -#define LIBXML_VERSION_STRING "20700" +#define LIBXML_VERSION_STRING "20701" /** * LIBXML_VERSION_EXTRA: @@ -58,7 +58,7 @@ XMLPUBFUN void XMLCALL xmlCheckVersion(int version); * Macro to check that the libxml version in use is compatible with * the version the software has been compiled against */ -#define LIBXML_TEST_VERSION xmlCheckVersion(20700); +#define LIBXML_TEST_VERSION xmlCheckVersion(20701); #ifndef VMS #if 0 diff --git a/libxml2.spec b/libxml2.spec index 37ee12c..039c198 100644 --- a/libxml2.spec +++ b/libxml2.spec @@ -1,6 +1,6 @@ Summary: Library providing XML and HTML support Name: libxml2 -Version: 2.7.0 +Version: 2.7.1 Release: 1 License: MIT Group: Development/Libraries @@ -128,6 +128,6 @@ rm -fr %{buildroot} %doc doc/python.html %changelog -* Sat Aug 30 2008 Daniel Veillard -- upstream release 2.7.0 see http://xmlsoft.org/news.html +* Mon Sep 1 2008 Daniel Veillard +- upstream release 2.7.1 see http://xmlsoft.org/news.html diff --git a/parser.c b/parser.c index 42b2852..9876a46 100644 --- a/parser.c +++ b/parser.c @@ -8694,7 +8694,7 @@ reparse: "xmlns: '%s' is not a valid URI\n", URL, NULL, NULL); } else { - if ((ctxt->pedantic) && (uri->scheme == NULL)) { + if (uri->scheme == NULL) { xmlNsWarn(ctxt, XML_WAR_NS_URI_RELATIVE, "xmlns: URI %s is not absolute\n", URL, NULL, NULL); diff --git a/python/libxml.c b/python/libxml.c index 95b3cb9..3f2ede7 100644 --- a/python/libxml.c +++ b/python/libxml.c @@ -24,6 +24,7 @@ #include #include #include +#include #include "libxml_wrap.h" #include "libxml2-py.h" @@ -2761,6 +2762,9 @@ libxml_serializeNode(ATTRIBUTE_UNUSED PyObject * self, PyObject * args) const char *encoding; int format; int len; + xmlSaveCtxtPtr ctxt; + xmlBufferPtr buf; + int options = 0; if (!PyArg_ParseTuple(args, (char *) "Ozi:serializeNode", &pyobj_node, &encoding, &format)) @@ -2773,137 +2777,52 @@ libxml_serializeNode(ATTRIBUTE_UNUSED PyObject * self, PyObject * args) } if (node->type == XML_DOCUMENT_NODE) { doc = (xmlDocPtr) node; - xmlDocDumpFormatMemoryEnc(doc, &c_retval, &len, - (const char *) encoding, format); - py_retval = libxml_charPtrWrap((char *) c_retval); + node = NULL; #ifdef LIBXML_HTML_ENABLED } else if (node->type == XML_HTML_DOCUMENT_NODE) { - xmlOutputBufferPtr buf; - xmlCharEncodingHandlerPtr handler = NULL; - doc = (xmlDocPtr) node; - if (encoding != NULL) - htmlSetMetaEncoding(doc, (const xmlChar *) encoding); - encoding = (const char *) htmlGetMetaEncoding(doc); - - if (encoding != NULL) { - handler = xmlFindCharEncodingHandler(encoding); - if (handler == NULL) { - Py_INCREF(Py_None); - return (Py_None); - } - } - - /* - * Fallback to HTML or ASCII when the encoding is unspecified - */ - if (handler == NULL) - handler = xmlFindCharEncodingHandler("HTML"); - if (handler == NULL) - handler = xmlFindCharEncodingHandler("ascii"); - - buf = xmlAllocOutputBuffer(handler); - if (buf == NULL) { - Py_INCREF(Py_None); - return (Py_None); - } - htmlDocContentDumpFormatOutput(buf, doc, encoding, format); - xmlOutputBufferFlush(buf); - if (buf->conv != NULL) { - len = buf->conv->use; - c_retval = buf->conv->content; - buf->conv->content = NULL; - } else { - len = buf->buffer->use; - c_retval = buf->buffer->content; - buf->buffer->content = NULL; - } - (void) xmlOutputBufferClose(buf); - py_retval = libxml_charPtrWrap((char *) c_retval); -#endif /* LIBXML_HTML_ENABLED */ + node = NULL; +#endif } else { if (node->type == XML_NAMESPACE_DECL) doc = NULL; else doc = node->doc; if ((doc == NULL) || (doc->type == XML_DOCUMENT_NODE)) { - xmlOutputBufferPtr buf; - xmlCharEncodingHandlerPtr handler = NULL; - - if (encoding != NULL) { - handler = xmlFindCharEncodingHandler(encoding); - if (handler == NULL) { - Py_INCREF(Py_None); - return (Py_None); - } - } - - buf = xmlAllocOutputBuffer(handler); - if (buf == NULL) { - Py_INCREF(Py_None); - return (Py_None); - } - xmlNodeDumpOutput(buf, doc, node, 0, format, encoding); - xmlOutputBufferFlush(buf); - if (buf->conv != NULL) { - len = buf->conv->use; - c_retval = buf->conv->content; - buf->conv->content = NULL; - } else { - len = buf->buffer->use; - c_retval = buf->buffer->content; - buf->buffer->content = NULL; - } - (void) xmlOutputBufferClose(buf); - py_retval = libxml_charPtrWrap((char *) c_retval); #ifdef LIBXML_HTML_ENABLED } else if (doc->type == XML_HTML_DOCUMENT_NODE) { - xmlOutputBufferPtr buf; - xmlCharEncodingHandlerPtr handler = NULL; - - if (encoding != NULL) - htmlSetMetaEncoding(doc, (const xmlChar *) encoding); - encoding = (const char *) htmlGetMetaEncoding(doc); - if (encoding != NULL) { - handler = xmlFindCharEncodingHandler(encoding); - if (handler == NULL) { - Py_INCREF(Py_None); - return (Py_None); - } - } - - /* - * Fallback to HTML or ASCII when the encoding is unspecified - */ - if (handler == NULL) - handler = xmlFindCharEncodingHandler("HTML"); - if (handler == NULL) - handler = xmlFindCharEncodingHandler("ascii"); - - buf = xmlAllocOutputBuffer(handler); - if (buf == NULL) { - Py_INCREF(Py_None); - return (Py_None); - } - htmlNodeDumpFormatOutput(buf, doc, node, encoding, format); - xmlOutputBufferFlush(buf); - if (buf->conv != NULL) { - len = buf->conv->use; - c_retval = buf->conv->content; - buf->conv->content = NULL; - } else { - len = buf->buffer->use; - c_retval = buf->buffer->content; - buf->buffer->content = NULL; - } - (void) xmlOutputBufferClose(buf); - py_retval = libxml_charPtrWrap((char *) c_retval); #endif /* LIBXML_HTML_ENABLED */ } else { Py_INCREF(Py_None); return (Py_None); } } + + + buf = xmlBufferCreate(); + if (buf == NULL) { + Py_INCREF(Py_None); + return (Py_None); + } + if (format) options |= XML_SAVE_FORMAT; + ctxt = xmlSaveToBuffer(buf, encoding, options); + if (ctxt == NULL) { + xmlBufferFree(buf); + Py_INCREF(Py_None); + return (Py_None); + } + if (node == NULL) + xmlSaveDoc(ctxt, doc); + else + xmlSaveTree(ctxt, node); + xmlSaveClose(ctxt); + + c_retval = buf->content; + buf->content = NULL; + + xmlBufferFree(buf); + py_retval = libxml_charPtrWrap((char *) c_retval); + return (py_retval); } diff --git a/python/setup.py b/python/setup.py index 723a4c9..75b3a40 100755 --- a/python/setup.py +++ b/python/setup.py @@ -226,7 +226,7 @@ else: setup (name = "libxml2-python", # On *nix, the version number is created from setup.py.in # On windows, it is set by configure.js - version = "2.7.0", + version = "2.7.1", description = descr, author = "Daniel Veillard", author_email = "veillard@redhat.com", diff --git a/python/tests/Makefile.am b/python/tests/Makefile.am index 8a85075..52c89fc 100644 --- a/python/tests/Makefile.am +++ b/python/tests/Makefile.am @@ -46,7 +46,8 @@ PYTESTS= \ validSchemas.py \ validRNG.py \ compareNodes.py \ - xpathns.py + xpathns.py \ + xpathleak.py XMLS= \ tst.xml \ diff --git a/python/tests/Makefile.in b/python/tests/Makefile.in index d7c00e5..ec3036f 100644 --- a/python/tests/Makefile.in +++ b/python/tests/Makefile.in @@ -317,7 +317,8 @@ PYTESTS = \ validSchemas.py \ validRNG.py \ compareNodes.py \ - xpathns.py + xpathns.py \ + xpathleak.py XMLS = \ tst.xml \ diff --git a/python/tests/xpathleak.py b/python/tests/xpathleak.py new file mode 100755 index 0000000..dcc144c --- /dev/null +++ b/python/tests/xpathleak.py @@ -0,0 +1,53 @@ +#!/usr/bin/python +import sys, libxml2 + +libxml2.debugMemory(True) + +expect="""--> Invalid expression +--> xmlXPathEval: evaluation failed +--> Invalid expression +--> xmlXPathEval: evaluation failed +--> Invalid expression +--> xmlXPathEval: evaluation failed +--> Invalid expression +--> xmlXPathEval: evaluation failed +--> Invalid expression +--> xmlXPathEval: evaluation failed +--> Invalid expression +--> xmlXPathEval: evaluation failed +""" +err="" +def callback(ctx, str): + global err + + err = err + "%s %s" % (ctx, str) + +libxml2.registerErrorHandler(callback, "-->") + +doc = libxml2.parseDoc("") +ctxt = doc.xpathNewContext() +ctxt.setContextNode(doc) +for expr in (":false()","bad:()","bad(:)",":bad(:)","bad:(:)","bad:bad(:)"): + try: + ctxt.xpathEval(expr) + except libxml2.xpathError, e: + pass + else: + print "Unexpectedly legal expression:", expr +ctxt.xpathFreeContext() +doc.freeDoc() + +if err != expect: + print "error" + print "received %s" %(err) + print "expected %s" %(expect) + sys.exit(1) + +libxml2.cleanupParser() +leakedbytes = libxml2.debugMemory(True) +if leakedbytes == 0: + print "OK" +else: + print "Memory leak", leakedbytes, "bytes" + # drop file to .memdump file in cwd, but won't work if not compiled in + libxml2.dumpMemory() diff --git a/runxmlconf.c b/runxmlconf.c index 0529058..8ef7f74 100644 --- a/runxmlconf.c +++ b/runxmlconf.c @@ -33,7 +33,7 @@ static FILE *logfile = NULL; static int verbose = 0; - +#define NB_EXPECTED_ERRORS 15 #if defined(_WIN32) && !defined(__CYGWIN__) @@ -588,10 +588,14 @@ main(int argc ATTRIBUTE_UNUSED, char **argv ATTRIBUTE_UNUSED) { printf("Total %d tests, no errors\n", nb_tests); } else { - ret = 1; + ret = 1; printf("Total %d tests, %d errors, %d leaks\n", nb_tests, nb_errors, nb_leaks); printf("See %s for detailed output\n", LOGFILE); + if ((nb_leaks == 0) && (nb_errors == NB_EXPECTED_ERRORS)) { + printf("%d errors were expected\n", nb_errors); + ret = 0; + } } xmlXPathFreeContext(ctxtXPath); xmlCleanupParser(); diff --git a/schematron.c b/schematron.c index 81f4704..03fa357 100644 --- a/schematron.c +++ b/schematron.c @@ -1691,7 +1691,7 @@ xmlSchematronValidateDoc(xmlSchematronValidCtxtPtr ctxt, xmlDocPtr instance) if (xmlPatternMatch(rule->pattern, cur) == 1) { test = rule->tests; while (test != NULL) { - xmlSchematronRunTest(ctxt, test, instance, cur, rule->pattern); + xmlSchematronRunTest(ctxt, test, instance, cur, (xmlSchematronPatternPtr)rule->pattern); test = test->next; } } diff --git a/testapi.c b/testapi.c index 037f7e4..6f85910 100644 --- a/testapi.c +++ b/testapi.c @@ -599,9 +599,10 @@ static void des_xmlTextReaderPtr(int no ATTRIBUTE_UNUSED, xmlTextReaderPtr val, #endif #define gen_nb_xmlBufferPtr 3 +static const char *static_buf_content = "a static buffer"; static xmlBufferPtr gen_xmlBufferPtr(int no, int nr ATTRIBUTE_UNUSED) { if (no == 0) return(xmlBufferCreate()); - if (no == 1) return(xmlBufferCreateStatic((void *)"a static buffer", 13)); + if (no == 1) return(xmlBufferCreateStatic((void *)static_buf_content, 13)); return(NULL); } static void des_xmlBufferPtr(int no ATTRIBUTE_UNUSED, xmlBufferPtr val, int nr ATTRIBUTE_UNUSED) { @@ -18827,6 +18828,7 @@ test_xmlBufferSetAllocationScheme(void) { scheme = gen_xmlBufferAllocationScheme(n_scheme, 1); xmlBufferSetAllocationScheme(buf, scheme); + if ((buf != NULL) && (scheme == XML_BUFFER_ALLOC_IMMUTABLE) && (buf->content != NULL) && (buf->content != static_buf_content)) { xmlFree(buf->content); buf->content = NULL;} call_tests++; des_xmlBufferPtr(n_buf, buf, 0); des_xmlBufferAllocationScheme(n_scheme, scheme, 1); diff --git a/tree.c b/tree.c index f26748e..76926fd 100644 --- a/tree.c +++ b/tree.c @@ -680,7 +680,9 @@ try_complex: */ void xmlSetBufferAllocationScheme(xmlBufferAllocationScheme scheme) { - xmlBufferAllocScheme = scheme; + if ((scheme == XML_BUFFER_ALLOC_EXACT) || + (scheme == XML_BUFFER_ALLOC_DOUBLEIT)) + xmlBufferAllocScheme = scheme; } /** @@ -6736,9 +6738,12 @@ xmlBufferSetAllocationScheme(xmlBufferPtr buf, #endif return; } - if (buf->alloc == XML_BUFFER_ALLOC_IMMUTABLE) return; - - buf->alloc = scheme; + if ((buf->alloc == XML_BUFFER_ALLOC_IMMUTABLE) || + (buf->alloc == XML_BUFFER_ALLOC_IO)) return; + if ((scheme == XML_BUFFER_ALLOC_DOUBLEIT) || + (scheme == XML_BUFFER_ALLOC_EXACT) || + (scheme == XML_BUFFER_ALLOC_IMMUTABLE)) + buf->alloc = scheme; } /** diff --git a/trionan.c b/trionan.c index a2482e6..e160370 100644 --- a/trionan.c +++ b/trionan.c @@ -1,6 +1,6 @@ /************************************************************************* * - * $Id: trionan.c 2219 2003-10-15 08:18:00Z veillard $ + * $Id: trionan.c 3790 2008-09-01 13:08:57Z veillard $ * * Copyright (C) 2001 Bjorn Reese * @@ -112,7 +112,7 @@ * Constants */ -static TRIO_CONST char rcsid[] = "@(#)$Id: trionan.c 2219 2003-10-15 08:18:00Z veillard $"; +static TRIO_CONST char rcsid[] = "@(#)$Id: trionan.c 3790 2008-09-01 13:08:57Z veillard $"; #if defined(USE_IEEE_754) @@ -129,7 +129,11 @@ static TRIO_CONST char rcsid[] = "@(#)$Id: trionan.c 2219 2003-10-15 08:18:00Z v */ #define TRIO_DOUBLE_INDEX(x) (((unsigned char *)&internalEndianMagic)[7-(x)]) +#if (defined(__BORLANDC__) && __BORLANDC__ >= 0x0590) +static TRIO_CONST double internalEndianMagic = 7.949928895127362e-275; +#else static TRIO_CONST double internalEndianMagic = 7.949928895127363e-275; +#endif /* Mask for the exponent */ static TRIO_CONST unsigned char ieee_754_exponent_mask[] = { diff --git a/xmlIO.c b/xmlIO.c index aa97c44..d4dc364 100644 --- a/xmlIO.c +++ b/xmlIO.c @@ -135,6 +135,9 @@ typedef struct _xmlOutputCallback { static xmlOutputCallback xmlOutputCallbackTable[MAX_OUTPUT_CALLBACK]; static int xmlOutputCallbackNr = 0; static int xmlOutputCallbackInitialized = 0; + +xmlOutputBufferPtr +xmlAllocOutputBufferInternal(xmlCharEncodingHandlerPtr encoder); #endif /* LIBXML_OUTPUT_ENABLED */ /************************************************************************ @@ -1720,7 +1723,7 @@ xmlIOHTTPOpenW(const char *post_uri, int compression) { /* Any character conversions should have been done before this */ - ctxt->doc_buff = xmlAllocOutputBuffer(NULL); + ctxt->doc_buff = xmlAllocOutputBufferInternal(NULL); } if (ctxt->doc_buff == NULL) { @@ -1731,7 +1734,7 @@ xmlIOHTTPOpenW(const char *post_uri, int compression) return (ctxt); } #endif /* LIBXML_OUTPUT_ENABLED */ - + #ifdef LIBXML_OUTPUT_ENABLED /** * xmlIOHTTPDfltOpenW @@ -2275,8 +2278,57 @@ xmlAllocOutputBuffer(xmlCharEncodingHandlerPtr encoder) { return(NULL); } + ret->encoder = encoder; + if (encoder != NULL) { + ret->conv = xmlBufferCreateSize(4000); + if (ret->conv == NULL) { + xmlFree(ret); + return(NULL); + } + + /* + * This call is designed to initiate the encoder state + */ + xmlCharEncOutFunc(encoder, ret->conv, NULL); + } else + ret->conv = NULL; + ret->writecallback = NULL; + ret->closecallback = NULL; + ret->context = NULL; + ret->written = 0; + + return(ret); +} + +/** + * xmlAllocOutputBufferInternal: + * @encoder: the encoding converter or NULL + * + * Create a buffered parser output + * + * Returns the new parser output or NULL + */ +xmlOutputBufferPtr +xmlAllocOutputBufferInternal(xmlCharEncodingHandlerPtr encoder) { + xmlOutputBufferPtr ret; + + ret = (xmlOutputBufferPtr) xmlMalloc(sizeof(xmlOutputBuffer)); + if (ret == NULL) { + xmlIOErrMemory("creating output buffer"); + return(NULL); + } + memset(ret, 0, (size_t) sizeof(xmlOutputBuffer)); + ret->buffer = xmlBufferCreate(); + if (ret->buffer == NULL) { + xmlFree(ret); + return(NULL); + } + + /* * For conversion buffers we use the special IO handling + * We don't do that from the exported API to avoid confusing + * user's code. */ ret->buffer->alloc = XML_BUFFER_ALLOC_IO; ret->buffer->contentIO = ret->buffer->content; @@ -2302,6 +2354,7 @@ xmlAllocOutputBuffer(xmlCharEncodingHandlerPtr encoder) { return(ret); } + #endif /* LIBXML_OUTPUT_ENABLED */ /** @@ -2502,7 +2555,7 @@ __xmlOutputBufferCreateFilename(const char *URI, if ((compression > 0) && (compression <= 9) && (is_file_uri == 1)) { context = xmlGzfileOpenW(unescaped, compression); if (context != NULL) { - ret = xmlAllocOutputBuffer(encoder); + ret = xmlAllocOutputBufferInternal(encoder); if (ret != NULL) { ret->context = context; ret->writecallback = xmlGzfileWrite; @@ -2539,7 +2592,7 @@ __xmlOutputBufferCreateFilename(const char *URI, if ((compression > 0) && (compression <= 9) && (is_file_uri == 1)) { context = xmlGzfileOpenW(URI, compression); if (context != NULL) { - ret = xmlAllocOutputBuffer(encoder); + ret = xmlAllocOutputBufferInternal(encoder); if (ret != NULL) { ret->context = context; ret->writecallback = xmlGzfileWrite; @@ -2572,7 +2625,7 @@ __xmlOutputBufferCreateFilename(const char *URI, /* * Allocate the Output buffer front-end. */ - ret = xmlAllocOutputBuffer(encoder); + ret = xmlAllocOutputBufferInternal(encoder); if (ret != NULL) { ret->context = context; ret->writecallback = xmlOutputCallbackTable[i].writecallback; @@ -2656,7 +2709,7 @@ xmlOutputBufferCreateFile(FILE *file, xmlCharEncodingHandlerPtr encoder) { if (file == NULL) return(NULL); - ret = xmlAllocOutputBuffer(encoder); + ret = xmlAllocOutputBufferInternal(encoder); if (ret != NULL) { ret->context = file; ret->writecallback = xmlFileWrite; @@ -2814,7 +2867,7 @@ xmlOutputBufferCreateFd(int fd, xmlCharEncodingHandlerPtr encoder) { if (fd < 0) return(NULL); - ret = xmlAllocOutputBuffer(encoder); + ret = xmlAllocOutputBufferInternal(encoder); if (ret != NULL) { ret->context = (void *) (long) fd; ret->writecallback = xmlFdWrite; @@ -2875,7 +2928,7 @@ xmlOutputBufferCreateIO(xmlOutputWriteCallback iowrite, if (iowrite == NULL) return(NULL); - ret = xmlAllocOutputBuffer(encoder); + ret = xmlAllocOutputBufferInternal(encoder); if (ret != NULL) { ret->context = (void *) ioctx; ret->writecallback = iowrite; diff --git a/xmlsave.c b/xmlsave.c index 2a61577..a650722 100644 --- a/xmlsave.c +++ b/xmlsave.c @@ -457,6 +457,40 @@ xmlAttrSerializeContent(xmlOutputBufferPtr buf, xmlAttrPtr attr) * * ************************************************************************/ +static int xmlSaveSwitchEncoding(xmlSaveCtxtPtr ctxt, const char *encoding) { + xmlOutputBufferPtr buf = ctxt->buf; + + if ((encoding != NULL) && (buf->encoder == NULL) && (buf->conv == NULL)) { + buf->encoder = xmlFindCharEncodingHandler((const char *)encoding); + if (buf->encoder == NULL) { + xmlSaveErr(XML_SAVE_UNKNOWN_ENCODING, NULL, + (const char *)encoding); + return(-1); + } + buf->conv = xmlBufferCreate(); + if (buf->conv == NULL) { + xmlCharEncCloseFunc(buf->encoder); + xmlSaveErrMemory("creating encoding buffer"); + return(-1); + } + /* + * initialize the state, e.g. if outputting a BOM + */ + xmlCharEncOutFunc(buf->encoder, buf->conv, NULL); + } + return(0); +} + +static int xmlSaveClearEncoding(xmlSaveCtxtPtr ctxt) { + xmlOutputBufferPtr buf = ctxt->buf; + xmlOutputBufferFlush(buf); + xmlCharEncCloseFunc(buf->encoder); + xmlBufferFree(buf->conv); + buf->encoder = NULL; + buf->conv = NULL; + return(0); +} + #ifdef LIBXML_HTML_ENABLED static void xhtmlNodeDumpOutput(xmlSaveCtxtPtr ctxt, xmlNodePtr cur); @@ -638,6 +672,66 @@ xmlNodeListDumpOutput(xmlSaveCtxtPtr ctxt, xmlNodePtr cur) { } } +#ifdef LIBXML_HTML_ENABLED +/** + * xmlNodeDumpOutputInternal: + * @cur: the current node + * + * Dump an HTML node, recursive behaviour, children are printed too. + */ +static int +htmlNodeDumpOutputInternal(xmlSaveCtxtPtr ctxt, xmlNodePtr cur) { + const xmlChar *oldenc = NULL; + const xmlChar *oldctxtenc = ctxt->encoding; + const xmlChar *encoding = ctxt->encoding; + xmlOutputBufferPtr buf = ctxt->buf; + int switched_encoding = 0; + xmlDocPtr doc; + + xmlInitParser(); + + doc = cur->doc; { + if (doc != NULL) + oldenc = doc->encoding; + if (ctxt->encoding != NULL) { + doc->encoding = BAD_CAST ctxt->encoding; + } else if (doc->encoding != NULL) { + encoding = doc->encoding; + } + } + + if ((encoding != NULL) && (doc != NULL)) + htmlSetMetaEncoding(doc, (const xmlChar *) encoding); + if ((encoding == NULL) && (doc != NULL)) + encoding = htmlGetMetaEncoding(doc); + if (encoding == NULL) + encoding = BAD_CAST "HTML"; + if ((encoding != NULL) && (oldctxtenc == NULL) && + (buf->encoder == NULL) && (buf->conv == NULL)) { + if (xmlSaveSwitchEncoding(ctxt, (const char*) encoding) < 0) { + doc->encoding = oldenc; + return(-1); + } + switched_encoding = 1; + } + if (ctxt->options & XML_SAVE_FORMAT) + htmlNodeDumpFormatOutput(buf, doc, cur, + (const char *)encoding, 1); + else + htmlNodeDumpFormatOutput(buf, doc, cur, + (const char *)encoding, 0); + /* + * Restore the state of the saving context at the end of the document + */ + if ((switched_encoding) && (oldctxtenc == NULL)) { + xmlSaveClearEncoding(ctxt); + } + if (doc != NULL) + doc->encoding = oldenc; + return(0); +} +#endif + /** * xmlNodeDumpOutputInternal: * @cur: the current node @@ -662,6 +756,13 @@ xmlNodeDumpOutputInternal(xmlSaveCtxtPtr ctxt, xmlNodePtr cur) { xmlDocContentDumpOutput(ctxt, (xmlDocPtr) cur); return; } +#ifdef LIBXML_HTML_ENABLED + if ((cur->type != XML_NAMESPACE_DECL) && (cur->doc != NULL) && + (cur->doc->type == XML_HTML_DOCUMENT_NODE)) { + htmlNodeDumpOutputInternal(ctxt, cur); + return; + } +#endif if (cur->type == XML_DTD_NODE) { xmlDtdDumpOutput(ctxt, (xmlDtdPtr) cur); return; @@ -835,9 +936,14 @@ xmlDocContentDumpOutput(xmlSaveCtxtPtr ctxt, xmlDocPtr cur) { xmlCharEncodingOutputFunc oldescapeAttr = ctxt->escapeAttr; xmlOutputBufferPtr buf = ctxt->buf; xmlCharEncoding enc; + int switched_encoding = 0; xmlInitParser(); + if ((cur->type != XML_HTML_DOCUMENT_NODE) && + (cur->type != XML_DOCUMENT_NODE)) + return(-1); + if (ctxt->encoding != NULL) { cur->encoding = BAD_CAST ctxt->encoding; } else if (cur->encoding != NULL) { @@ -847,110 +953,119 @@ xmlDocContentDumpOutput(xmlSaveCtxtPtr ctxt, xmlDocPtr cur) { xmlGetCharEncodingName((xmlCharEncoding) cur->charset); } - enc = xmlParseCharEncoding((const char*) encoding); - if ((encoding != NULL) && (oldctxtenc == NULL) && - (buf->encoder == NULL) && (buf->conv == NULL) && - ((ctxt->options & XML_SAVE_NO_DECL) == 0)) { - if ((enc != XML_CHAR_ENCODING_UTF8) && - (enc != XML_CHAR_ENCODING_NONE) && - (enc != XML_CHAR_ENCODING_ASCII)) { - /* - * we need to switch to this encoding but just for this document - * since we output the XMLDecl the conversion must be done to not - * generate not well formed documents. - */ - buf->encoder = xmlFindCharEncodingHandler((const char *)encoding); - if (buf->encoder == NULL) { - xmlSaveErr(XML_SAVE_UNKNOWN_ENCODING, NULL, - (const char *)encoding); + if (cur->type == XML_HTML_DOCUMENT_NODE) { +#ifdef LIBXML_HTML_ENABLED + if (encoding != NULL) + htmlSetMetaEncoding(cur, (const xmlChar *) encoding); + if (encoding == NULL) + encoding = htmlGetMetaEncoding(cur); + if (encoding == NULL) + encoding = BAD_CAST "HTML"; + if ((encoding != NULL) && (oldctxtenc == NULL) && + (buf->encoder == NULL) && (buf->conv == NULL)) { + if (xmlSaveSwitchEncoding(ctxt, (const char*) encoding) < 0) { + cur->encoding = oldenc; return(-1); } - buf->conv = xmlBufferCreate(); - if (buf->conv == NULL) { - xmlCharEncCloseFunc(buf->encoder); - xmlSaveErrMemory("creating encoding buffer"); - return(-1); + switched_encoding = 1; + } + if (ctxt->options & XML_SAVE_FORMAT) + htmlDocContentDumpFormatOutput(buf, cur, + (const char *)encoding, 1); + else + htmlDocContentDumpFormatOutput(buf, cur, + (const char *)encoding, 0); + if (ctxt->encoding != NULL) + cur->encoding = oldenc; + return(0); +#else + return(-1); +#endif + } else if (cur->type == XML_DOCUMENT_NODE) { + enc = xmlParseCharEncoding((const char*) encoding); + if ((encoding != NULL) && (oldctxtenc == NULL) && + (buf->encoder == NULL) && (buf->conv == NULL) && + ((ctxt->options & XML_SAVE_NO_DECL) == 0)) { + if ((enc != XML_CHAR_ENCODING_UTF8) && + (enc != XML_CHAR_ENCODING_NONE) && + (enc != XML_CHAR_ENCODING_ASCII)) { + /* + * we need to switch to this encoding but just for this + * document since we output the XMLDecl the conversion + * must be done to not generate not well formed documents. + */ + if (xmlSaveSwitchEncoding(ctxt, (const char*) encoding) < 0) { + cur->encoding = oldenc; + return(-1); + } + switched_encoding = 1; } - /* - * initialize the state, e.g. if outputting a BOM - */ - xmlCharEncOutFunc(buf->encoder, buf->conv, NULL); + if (ctxt->escape == xmlEscapeEntities) + ctxt->escape = NULL; + if (ctxt->escapeAttr == xmlEscapeEntities) + ctxt->escapeAttr = NULL; } - if (ctxt->escape == xmlEscapeEntities) - ctxt->escape = NULL; - if (ctxt->escapeAttr == xmlEscapeEntities) - ctxt->escapeAttr = NULL; - } - /* - * Save the XML declaration - */ - if ((ctxt->options & XML_SAVE_NO_DECL) == 0) { - xmlOutputBufferWrite(buf, 14, "version != NULL) - xmlBufferWriteQuotedString(buf->buffer, cur->version); - else - xmlOutputBufferWrite(buf, 5, "\"1.0\""); - if (encoding != NULL) { - xmlOutputBufferWrite(buf, 10, " encoding="); - xmlBufferWriteQuotedString(buf->buffer, (xmlChar *) encoding); - } - switch (cur->standalone) { - case 0: - xmlOutputBufferWrite(buf, 16, " standalone=\"no\""); - break; - case 1: - xmlOutputBufferWrite(buf, 17, " standalone=\"yes\""); - break; + /* + * Save the XML declaration + */ + if ((ctxt->options & XML_SAVE_NO_DECL) == 0) { + xmlOutputBufferWrite(buf, 14, "version != NULL) + xmlBufferWriteQuotedString(buf->buffer, cur->version); + else + xmlOutputBufferWrite(buf, 5, "\"1.0\""); + if (encoding != NULL) { + xmlOutputBufferWrite(buf, 10, " encoding="); + xmlBufferWriteQuotedString(buf->buffer, (xmlChar *) encoding); + } + switch (cur->standalone) { + case 0: + xmlOutputBufferWrite(buf, 16, " standalone=\"no\""); + break; + case 1: + xmlOutputBufferWrite(buf, 17, " standalone=\"yes\""); + break; + } + xmlOutputBufferWrite(buf, 3, "?>\n"); } - xmlOutputBufferWrite(buf, 3, "?>\n"); - } #ifdef LIBXML_HTML_ENABLED - if ((ctxt->options & XML_SAVE_NO_XHTML) == 0) { - dtd = xmlGetIntSubset(cur); - if (dtd != NULL) { - is_xhtml = xmlIsXHTML(dtd->SystemID, dtd->ExternalID); - if (is_xhtml < 0) is_xhtml = 0; + if ((ctxt->options & XML_SAVE_NO_XHTML) == 0) { + dtd = xmlGetIntSubset(cur); + if (dtd != NULL) { + is_xhtml = xmlIsXHTML(dtd->SystemID, dtd->ExternalID); + if (is_xhtml < 0) is_xhtml = 0; + } } - } #endif - if (cur->children != NULL) { - xmlNodePtr child = cur->children; + if (cur->children != NULL) { + xmlNodePtr child = cur->children; - while (child != NULL) { - ctxt->level = 0; + while (child != NULL) { + ctxt->level = 0; #ifdef LIBXML_HTML_ENABLED - if (is_xhtml) - xhtmlNodeDumpOutput(ctxt, child); - else + if (is_xhtml) + xhtmlNodeDumpOutput(ctxt, child); + else #endif - xmlNodeDumpOutputInternal(ctxt, child); - xmlOutputBufferWrite(buf, 1, "\n"); - child = child->next; + xmlNodeDumpOutputInternal(ctxt, child); + xmlOutputBufferWrite(buf, 1, "\n"); + child = child->next; + } } } - if (ctxt->encoding != NULL) - cur->encoding = oldenc; - + /* * Restore the state of the saving context at the end of the document */ - if ((encoding != NULL) && (oldctxtenc == NULL) && - ((ctxt->options & XML_SAVE_NO_DECL) == 0)) { - if ((enc != XML_CHAR_ENCODING_UTF8) && - (enc != XML_CHAR_ENCODING_NONE) && - (enc != XML_CHAR_ENCODING_ASCII)) { - xmlOutputBufferFlush(buf); - xmlCharEncCloseFunc(buf->encoder); - xmlBufferFree(buf->conv); - buf->encoder = NULL; - buf->conv = NULL; - } + if ((switched_encoding) && (oldctxtenc == NULL)) { + xmlSaveClearEncoding(ctxt); ctxt->escape = oldescape; ctxt->escapeAttr = oldescapeAttr; } + cur->encoding = oldenc; return(0); } diff --git a/xpath.c b/xpath.c index cfa3f69..514262f 100644 --- a/xpath.c +++ b/xpath.c @@ -187,11 +187,11 @@ xmlXPathGetSign(double val) { * TODO: when compatibility allows remove all "fake node libxslt" strings * the test should just be name[0] = ' ' */ -/* #define DEBUG */ -/* #define DEBUG_STEP */ -/* #define DEBUG_STEP_NTH */ -/* #define DEBUG_EXPR */ -/* #define DEBUG_EVAL_COUNTS */ +#ifdef DEBUG_XPATH_EXPRESSION +#define DEBUG_STEP +#define DEBUG_EXPR +#define DEBUG_EVAL_COUNTS +#endif static xmlNs xmlXPathXMLNamespaceStruct = { NULL, @@ -9778,7 +9778,7 @@ xmlXPathParseQName(xmlXPathParserContextPtr ctxt, xmlChar **prefix) { *prefix = NULL; ret = xmlXPathParseNCName(ctxt); - if (CUR == ':') { + if (ret && CUR == ':') { *prefix = ret; NEXT; ret = xmlXPathParseNCName(ctxt); @@ -10274,6 +10274,7 @@ xmlXPathCompFunctionCall(xmlXPathParserContextPtr ctxt) { name = xmlXPathParseQName(ctxt, &prefix); if (name == NULL) { + xmlFree(prefix); XP_ERROR(XPATH_EXPR_ERROR); } SKIP_BLANKS; @@ -10306,7 +10307,11 @@ xmlXPathCompFunctionCall(xmlXPathParserContextPtr ctxt) { int op1 = ctxt->comp->last; ctxt->comp->last = -1; xmlXPathCompileExpr(ctxt, sort); - CHECK_ERROR; + if (ctxt->error != XPATH_EXPRESSION_OK) { + xmlFree(name); + xmlFree(prefix); + return; + } PUSH_BINARY_EXPR(XPATH_OP_ARG, op1, ctxt->comp->last, 0, 0); nbargs++; if (CUR == ')') break; @@ -11401,12 +11406,11 @@ xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op); #ifdef DEBUG_STEP static void -xmlXPathDebugDumpStepAxis(xmlXPathAxisVal axis, - xmlXPathTestVal test, +xmlXPathDebugDumpStepAxis(xmlXPathStepOpPtr op, int nbNodes) { xmlGenericError(xmlGenericErrorContext, "new step : "); - switch (axis) { + switch (op->value) { case AXIS_ANCESTOR: xmlGenericError(xmlGenericErrorContext, "axis 'ancestors' "); break; @@ -11453,14 +11457,14 @@ xmlXPathDebugDumpStepAxis(xmlXPathAxisVal axis, } xmlGenericError(xmlGenericErrorContext, " context contains %d nodes\n", nbNodes); - switch (test) { + switch (op->value2) { case NODE_TEST_NONE: xmlGenericError(xmlGenericErrorContext, " searching for none !!!\n"); break; case NODE_TEST_TYPE: xmlGenericError(xmlGenericErrorContext, - " searching for type %d\n", type); + " searching for type %d\n", op->value3); break; case NODE_TEST_PI: xmlGenericError(xmlGenericErrorContext, @@ -11473,14 +11477,14 @@ xmlXPathDebugDumpStepAxis(xmlXPathAxisVal axis, case NODE_TEST_NS: xmlGenericError(xmlGenericErrorContext, " searching for namespace %s\n", - prefix); + op->value5); break; case NODE_TEST_NAME: xmlGenericError(xmlGenericErrorContext, - " searching for name %s\n", name); - if (prefix != NULL) + " searching for name %s\n", op->value5); + if (op->value4) xmlGenericError(xmlGenericErrorContext, - " with namespace %s\n", prefix); + " with namespace %s\n", op->value4); break; } xmlGenericError(xmlGenericErrorContext, "Testing : "); @@ -12055,8 +12059,8 @@ xmlXPathNodeCollectAndTest(xmlXPathParserContextPtr ctxt, } #ifdef DEBUG_STEP - xmlXPathDebugDumpStepAxis(axis, test, - (obj->nodesetval != NULL) ? obj->nodsetval->nodeNr : 0); + xmlXPathDebugDumpStepAxis(op, + (obj->nodesetval != NULL) ? obj->nodesetval->nodeNr : 0); #endif if (next == NULL) { -- cgit v1.2.3