summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog35
-rw-r--r--HTMLtree.c7
-rw-r--r--Makefile.am4
-rw-r--r--Makefile.in4
-rw-r--r--NEWS35
-rwxr-xr-xconfigure2
-rw-r--r--configure.in2
-rw-r--r--doc/libxml2.xsa61
-rw-r--r--doc/news.html7
-rw-r--r--doc/xml.html9
-rwxr-xr-xgentest.py1
-rw-r--r--include/libxml/xmlversion.h8
-rw-r--r--libxml2.spec6
-rw-r--r--parser.c2
-rw-r--r--python/libxml.c147
-rwxr-xr-xpython/setup.py2
-rw-r--r--python/tests/Makefile.am3
-rw-r--r--python/tests/Makefile.in3
-rwxr-xr-xpython/tests/xpathleak.py53
-rw-r--r--runxmlconf.c8
-rw-r--r--schematron.c2
-rw-r--r--testapi.c4
-rw-r--r--tree.c13
-rw-r--r--trionan.c8
-rw-r--r--xmlIO.c69
-rw-r--r--xmlsave.c279
-rw-r--r--xpath.c40
27 files changed, 530 insertions, 284 deletions
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 <daniel@veillard.com>
+
+ * 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 <daniel@veillard.com>
+
+ * 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 <daniel@veillard.com>
+
+ * 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 <daniel@veillard.com>
+
+ * 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 <daniel@veillard.com>
* 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 @@
</vendor>
<product id="libxml2">
<name>libxml2</name>
- <version>2.6.32</version>
- <last-release> Apr 8 2008</last-release>
+ <version>2.7.0</version>
+ <last-release> Aug 30 2008</last-release>
<info-url>http://xmlsoft.org/</info-url>
- <changes> - 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)
+ <changes> - 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
</changes>
</product>
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</p><ul><li>More testing on RelaxNG</li>
<li>Finishing up <a href="http://www.w3.org/TR/xmlschema-1/">XML
Schemas</a></li>
</ul><p>The <a href="ChangeLog.html">change log</a> describes the recents commits
-to the <a href="http://svn.gnome.org/viewcvs/libxml2/trunk/">SVN</a> code base.</p><p>Here is the list of public releases:</p><h3>2.7.0: Aug 30 2008</h3><ul><li>Documentation: switch ChangeLog to UTF-8, improve mutithreads and
+to the <a href="http://svn.gnome.org/viewcvs/libxml2/trunk/">SVN</a> code base.</p><p>Here is the list of public releases:</p><h3>2.7.1: Sep 1 2008</h3><ul><li>Portability fix: Borland C fix (Moritz Both)</li>
+ <li>Bug fixes: python serialization wrappers, XPath QName corner
+ case handking and leaks (Martin)</li>
+ <li>Improvement: extend the xmlSave to handle HTML documents and trees</li>
+ <li>Cleanup: python serialization wrappers</li>
+</ul><h3>2.7.0: Aug 30 2008</h3><ul><li>Documentation: switch ChangeLog to UTF-8, improve mutithreads and
xmlParserCleanup docs</li>
<li>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 <a href="http://svn.gnome.org/viewcvs/libxml2/trunk/">SVN</a> code base.<
<p>Here is the list of public releases:</p>
+<h3>2.7.1: Sep 1 2008</h3>
+<ul>
+ <li>Portability fix: Borland C fix (Moritz Both)</li>
+ <li>Bug fixes: python serialization wrappers, XPath QName corner
+ case handking and leaks (Martin)</li>
+ <li>Improvement: extend the xmlSave to handle HTML documents and trees</li>
+ <li>Cleanup: python serialization wrappers</li>
+</ul>
+
<h3>2.7.0: Aug 30 2008</h3>
<ul>
<li>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 <veillard@redhat.com>
-- upstream release 2.7.0 see http://xmlsoft.org/news.html
+* Mon Sep 1 2008 Daniel Veillard <veillard@redhat.com>
+- 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 <libxml/xmlIO.h>
#include <libxml/c14n.h>
#include <libxml/xmlreader.h>
+#include <libxml/xmlsave.h>
#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("<fish/>")
+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 <breese@users.sourceforge.net>
*
@@ -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, "<?xml version=");
- if (cur->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, "<?xml version=");
+ if (cur->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) {