aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTreehugger Robot <treehugger-gerrit@google.com>2021-08-23 18:10:00 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2021-08-23 18:10:00 +0000
commit3d0ede76332cfa61d30a10019911f3e63603e676 (patch)
tree9e7d9ca436e95ae9f777b4c2cda32786de1d1bf3
parentd72d938c5c9329603df4b819f1ec4e1eeed72389 (diff)
parent60f5c1697467c5472252b9fbe8fe5bca7de37cc3 (diff)
downloadlibxml2-3d0ede76332cfa61d30a10019911f3e63603e676.tar.gz
Merge "Upgrade libxml2 to dea91c97debeac7c1aaf9c19f79029809e23a353"android-s-beta-5android-s-beta-5
-rw-r--r--CMakeLists.txt19
-rw-r--r--HTMLtree.c52
-rw-r--r--INSTALL.libxml220
-rw-r--r--METADATA8
-rw-r--r--configure.ac2
-rw-r--r--doc/FAQ.html14
-rw-r--r--doc/xml.html14
-rw-r--r--encoding.c3
-rw-r--r--fuzz/Makefile.am2
-rw-r--r--include/libxml/Makefile.am2
-rw-r--r--parser.c3
-rw-r--r--xmlIO.c20
-rw-r--r--xmlregexp.c9
-rw-r--r--xmlsave.c31
-rw-r--r--xpath.c2
15 files changed, 133 insertions, 68 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index a437717b..073869fc 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,6 +1,16 @@
cmake_minimum_required(VERSION 3.15)
-project(libxml2 VERSION 2.9.10 LANGUAGES C)
+file(STRINGS "configure.ac" CONFIGURE_AC_LINES)
+foreach(line ${CONFIGURE_AC_LINES})
+ if(line MATCHES [[^m4_define\(\[(MAJOR_VERSION|MINOR_VERSION|MICRO_VERSION)\],[ \t]*([0-9]+)\)$]])
+ set(LIBXML_${CMAKE_MATCH_1} ${CMAKE_MATCH_2})
+ elseif(line MATCHES "^(LIBXML_MAJOR_VERSION|LIBXML_MINOR_VERSION|LIBXML_MICRO_VERSION)=([0-9]+)$")
+ set(${CMAKE_MATCH_1} ${CMAKE_MATCH_2})
+ endif()
+endforeach()
+set(VERSION "${LIBXML_MAJOR_VERSION}.${LIBXML_MINOR_VERSION}.${LIBXML_MICRO_VERSION}")
+
+project(libxml2 VERSION ${VERSION} LANGUAGES C)
include(CheckCSourceCompiles)
include(CheckFunctionExists)
@@ -95,11 +105,6 @@ foreach(VARIABLE IN ITEMS WITH_AUTOMATA WITH_C14N WITH_CATALOG WITH_DEBUG WITH_D
endif()
endforeach()
-set(LIBXML_MAJOR_VERSION ${PROJECT_VERSION_MAJOR})
-set(LIBXML_MINOR_VERSION ${PROJECT_VERSION_MINOR})
-set(LIBXML_MICRO_VERSION ${PROJECT_VERSION_PATCH})
-
-set(VERSION "${LIBXML_MAJOR_VERSION}.${LIBXML_MINOR_VERSION}.${LIBXML_MICRO_VERSION}")
set(LIBXML_VERSION ${LIBXML_MAJOR_VERSION}0${LIBXML_MINOR_VERSION}0${LIBXML_MICRO_VERSION})
set(LIBXML_VERSION_STRING "${LIBXML_VERSION}")
set(LIBXML_VERSION_EXTRA "")
@@ -414,6 +419,7 @@ if(LIBXML2_WITH_TRIO)
endif()
add_library(LibXml2 ${LIBXML2_HDRS} ${LIBXML2_SRCS})
+add_library(LibXml2::LibXml2 ALIAS LibXml2)
if(NOT BUILD_SHARED_LIBS)
target_compile_definitions(LibXml2 INTERFACE LIBXML_STATIC)
@@ -537,6 +543,7 @@ if(LIBXML2_WITH_PROGRAMS)
)
foreach(PROGRAM ${PROGRAMS})
add_executable(${PROGRAM} ${PROGRAM}.c)
+ add_executable(LibXml2::${PROGRAM} ALIAS ${PROGRAM})
target_link_libraries(${PROGRAM} LibXml2)
if(HAVE_LIBHISTORY)
target_link_libraries(${PROGRAM} history)
diff --git a/HTMLtree.c b/HTMLtree.c
index 24434d45..7a2b8558 100644
--- a/HTMLtree.c
+++ b/HTMLtree.c
@@ -744,7 +744,7 @@ void
htmlNodeDumpFormatOutput(xmlOutputBufferPtr buf, xmlDocPtr doc,
xmlNodePtr cur, const char *encoding ATTRIBUTE_UNUSED,
int format) {
- xmlNodePtr root;
+ xmlNodePtr root, parent;
xmlAttrPtr attr;
const htmlElemDesc * info;
@@ -755,6 +755,7 @@ htmlNodeDumpFormatOutput(xmlOutputBufferPtr buf, xmlDocPtr doc,
}
root = cur;
+ parent = cur->parent;
while (1) {
switch (cur->type) {
case XML_HTML_DOCUMENT_NODE:
@@ -763,13 +764,29 @@ htmlNodeDumpFormatOutput(xmlOutputBufferPtr buf, xmlDocPtr doc,
htmlDtdDumpOutput(buf, (xmlDocPtr) cur, NULL);
}
if (cur->children != NULL) {
- cur = cur->children;
- continue;
+ /* Always validate cur->parent when descending. */
+ if (cur->parent == parent) {
+ parent = cur;
+ cur = cur->children;
+ continue;
+ }
+ } else {
+ xmlOutputBufferWriteString(buf, "\n");
}
break;
case XML_ELEMENT_NODE:
/*
+ * Some users like lxml are known to pass nodes with a corrupted
+ * tree structure. Fall back to a recursive call to handle this
+ * case.
+ */
+ if ((cur->parent != parent) && (cur->children != NULL)) {
+ htmlNodeDumpFormatOutput(buf, doc, cur, encoding, format);
+ break;
+ }
+
+ /*
* Get specific HTML info for that node.
*/
if (cur->ns == NULL)
@@ -817,6 +834,7 @@ htmlNodeDumpFormatOutput(xmlOutputBufferPtr buf, xmlDocPtr doc,
(cur->name != NULL) &&
(cur->name[0] != 'p')) /* p, pre, param */
xmlOutputBufferWriteString(buf, "\n");
+ parent = cur;
cur = cur->children;
continue;
}
@@ -825,9 +843,9 @@ htmlNodeDumpFormatOutput(xmlOutputBufferPtr buf, xmlDocPtr doc,
(info != NULL) && (!info->isinline)) {
if ((cur->next->type != HTML_TEXT_NODE) &&
(cur->next->type != HTML_ENTITY_REF_NODE) &&
- (cur->parent != NULL) &&
- (cur->parent->name != NULL) &&
- (cur->parent->name[0] != 'p')) /* p, pre, param */
+ (parent != NULL) &&
+ (parent->name != NULL) &&
+ (parent->name[0] != 'p')) /* p, pre, param */
xmlOutputBufferWriteString(buf, "\n");
}
@@ -842,9 +860,9 @@ htmlNodeDumpFormatOutput(xmlOutputBufferPtr buf, xmlDocPtr doc,
break;
if (((cur->name == (const xmlChar *)xmlStringText) ||
(cur->name != (const xmlChar *)xmlStringTextNoenc)) &&
- ((cur->parent == NULL) ||
- ((xmlStrcasecmp(cur->parent->name, BAD_CAST "script")) &&
- (xmlStrcasecmp(cur->parent->name, BAD_CAST "style"))))) {
+ ((parent == NULL) ||
+ ((xmlStrcasecmp(parent->name, BAD_CAST "script")) &&
+ (xmlStrcasecmp(parent->name, BAD_CAST "style"))))) {
xmlChar *buffer;
buffer = xmlEncodeEntitiesReentrant(doc, cur->content);
@@ -902,13 +920,9 @@ htmlNodeDumpFormatOutput(xmlOutputBufferPtr buf, xmlDocPtr doc,
break;
}
- /*
- * The parent should never be NULL here but we want to handle
- * corrupted documents gracefully.
- */
- if (cur->parent == NULL)
- return;
- cur = cur->parent;
+ cur = parent;
+ /* cur->parent was validated when descending. */
+ parent = cur->parent;
if ((cur->type == XML_HTML_DOCUMENT_NODE) ||
(cur->type == XML_DOCUMENT_NODE)) {
@@ -939,9 +953,9 @@ htmlNodeDumpFormatOutput(xmlOutputBufferPtr buf, xmlDocPtr doc,
(cur->next != NULL)) {
if ((cur->next->type != HTML_TEXT_NODE) &&
(cur->next->type != HTML_ENTITY_REF_NODE) &&
- (cur->parent != NULL) &&
- (cur->parent->name != NULL) &&
- (cur->parent->name[0] != 'p')) /* p, pre, param */
+ (parent != NULL) &&
+ (parent->name != NULL) &&
+ (parent->name[0] != 'p')) /* p, pre, param */
xmlOutputBufferWriteString(buf, "\n");
}
}
diff --git a/INSTALL.libxml2 b/INSTALL.libxml2
index ac9211d6..d369ef69 100644
--- a/INSTALL.libxml2
+++ b/INSTALL.libxml2
@@ -27,6 +27,26 @@ Compilation
Please report test failures to the mailing list or bug tracker.
+ Another option for compiling libxml is using CMake:
+
+ cmake -E tar xf libxml2-xxx.tar.gz
+ cmake -S libxml2-xxx -B libxml2-xxx-build [possible options]
+ cmake --build libxml2-xxx-build
+ cmake --install libxml2-xxx-build
+
+ Common CMake options include:
+
+ -D BUILD_SHARED_LIBS=OFF # build static libraries
+ -D CMAKE_BUILD_TYPE=Release # specify build type
+ -D CMAKE_INSTALL_PREFIX=/usr/local # specify the install path
+ -D LIBXML2_WITH_ICONV=OFF # disable iconv
+ -D LIBXML2_WITH_LZMA=OFF # disable liblzma
+ -D LIBXML2_WITH_PYTHON=OFF # disable Python
+ -D LIBXML2_WITH_ZLIB=OFF # disable libz
+
+ You can also open the libxml source directory with its CMakeLists.txt
+ directly in various IDEs such as CLion, QtCreator, or Visual Studio.
+
2. What other libraries are needed to compile/install libxml?
Libxml does not require any other libraries. A platform with somewhat
diff --git a/METADATA b/METADATA
index e88ea8fd..b863408f 100644
--- a/METADATA
+++ b/METADATA
@@ -10,13 +10,13 @@ third_party {
}
url {
type: ARCHIVE
- value: "https://github.com/GNOME/libxml2/archive/e1bcffea180d6cc0651757bb64284a763e0e2239.zip"
+ value: "https://github.com/GNOME/libxml2/archive/dea91c97debeac7c1aaf9c19f79029809e23a353.zip"
}
- version: "e1bcffea180d6cc0651757bb64284a763e0e2239"
+ version: "dea91c97debeac7c1aaf9c19f79029809e23a353"
license_type: BY_EXCEPTION_ONLY
last_upgrade_date {
year: 2021
- month: 5
- day: 13
+ month: 8
+ day: 20
}
}
diff --git a/configure.ac b/configure.ac
index ab76a459..5b161a54 100644
--- a/configure.ac
+++ b/configure.ac
@@ -3,7 +3,7 @@ AC_PREREQ([2.63])
m4_define([MAJOR_VERSION], 2)
m4_define([MINOR_VERSION], 9)
-m4_define([MICRO_VERSION], 11)
+m4_define([MICRO_VERSION], 12)
AC_INIT([libxml2],[MAJOR_VERSION.MINOR_VERSION.MICRO_VERSION])
AC_CONFIG_SRCDIR([entities.c])
diff --git a/doc/FAQ.html b/doc/FAQ.html
index e80cef6a..91a29f32 100644
--- a/doc/FAQ.html
+++ b/doc/FAQ.html
@@ -26,15 +26,13 @@ A:link, A:visited, A:active { text-decoration: underline }
</li>
</ol><h3><a name="Installati" id="Installati">Installation</a></h3><ol>
<li><strong><span style="background-color: #FF0000">Do Not Use
- libxml1</span></strong>, use libxml2</li>
- <p></p>
+ libxml1</span></strong>, use libxml2<p></p></li>
<li><em>Where can I get libxml</em> ?
<p>The original distribution comes from <a href="ftp://xmlsoft.org/libxml2/">xmlsoft.org</a> or <a href="ftp://ftp.gnome.org/pub/GNOME/sources/libxml2/2.6/">gnome.org</a></p>
<p>Most Linux and BSD distributions include libxml, this is probably the
safer way for end-users to use libxml.</p>
<p>David Doolin provides precompiled Windows versions at <a href="http://www.ce.berkeley.edu/~doolin/code/libxmlwin32/ ">http://www.ce.berkeley.edu/~doolin/code/libxmlwin32/</a></p>
</li>
- <p></p>
<li><em>I see libxml and libxml2 releases, which one should I install ?</em>
<ul>
<li>If you are not constrained by backward compatibility issues with
@@ -50,6 +48,7 @@ A:link, A:visited, A:active { text-decoration: underline }
<li>If you are developing a new application, please develop against
libxml2(-devel)</li>
</ul>
+ <p></p>
</li>
<li><em>I can't install the libxml package, it conflicts with libxml0</em>
<p>You probably have an old libxml0 package used to provide the shared
@@ -95,8 +94,8 @@ A:link, A:visited, A:active { text-decoration: underline }
of the official UNIX</a> specification. Here is one <a href="http://www.gnu.org/software/libiconv/">implementation of the
library</a> which source can be found <a href="ftp://ftp.ilog.fr/pub/Users/haible/gnu/">here</a>.</li>
</ul>
+ <p></p>
</li>
- <p></p>
<li><em>Make check fails on some platforms</em>
<p>Sometimes the regression tests' results don't completely match the
value produced by the parser, and the makefile uses diff to print the
@@ -170,9 +169,8 @@ A:link, A:visited, A:active { text-decoration: underline }
default one, and this will <em>automatically</em> get the correct
libraries linked with your program.</li>
</ul>
+ <p></p>
</li>
-
- <p></p>
<li><em>xmlDocDump() generates output on one line.</em>
<p>Libxml2 will not <strong>invent</strong> spaces in the content of a
document since <strong>all spaces in the content of a document are
@@ -188,8 +186,8 @@ A:link, A:visited, A:active { text-decoration: underline }
()</a> and <a href="http://xmlsoft.org/html/libxml-tree.html#xmlSaveFormatFile">xmlSaveFormatFile
()</a></li>
</ol>
+ <p></p>
</li>
- <p></p>
<li><em>Extra nodes in the document:</em>
<p><em>For an XML file as below:</em></p>
<pre>&lt;?xml version="1.0"?&gt;
@@ -259,8 +257,8 @@ pnode=pxmlDoc-&gt;children-&gt;children;</pre>
of <a href="http://svn.gnome.org/viewvc/libxml2/trunk/xmllint.c?view=markup">xmllint.c</a> and of the various testXXX.c test programs should
provide good examples of how to do things with the library.</li>
</ul>
+ <p></p>
</li>
- <p></p>
<li><em>What about C++ ?</em>
<p>libxml2 is written in pure C in order to allow easy reuse on a number
of platforms, including embedded systems. I don't intend to convert to
diff --git a/doc/xml.html b/doc/xml.html
index 92360d84..eab6e2a2 100644
--- a/doc/xml.html
+++ b/doc/xml.html
@@ -189,8 +189,7 @@ libxml2</p>
<h3><a name="Installati">Installation</a></h3>
<ol>
<li><strong><span style="background-color: #FF0000">Do Not Use
- libxml1</span></strong>, use libxml2</li>
- <p></p>
+ libxml1</span></strong>, use libxml2<p></p></li>
<li><em>Where can I get libxml</em> ?
<p>The original distribution comes from <a
href="ftp://xmlsoft.org/libxml2/">xmlsoft.org</a> or <a
@@ -200,7 +199,6 @@ libxml2</p>
<p>David Doolin provides precompiled Windows versions at <a
href="http://www.ce.berkeley.edu/~doolin/code/libxmlwin32/ ">http://www.ce.berkeley.edu/~doolin/code/libxmlwin32/</a></p>
</li>
- <p></p>
<li><em>I see libxml and libxml2 releases, which one should I install ?</em>
<ul>
<li>If you are not constrained by backward compatibility issues with
@@ -220,6 +218,7 @@ libxml2</p>
<li>If you are developing a new application, please develop against
libxml2(-devel)</li>
</ul>
+ <p></p>
</li>
<li><em>I can't install the libxml package, it conflicts with libxml0</em>
<p>You probably have an old libxml0 package used to provide the shared
@@ -272,8 +271,8 @@ libxml2</p>
library</a> which source can be found <a
href="ftp://ftp.ilog.fr/pub/Users/haible/gnu/">here</a>.</li>
</ul>
+ <p></p>
</li>
- <p></p>
<li><em>Make check fails on some platforms</em>
<p>Sometimes the regression tests' results don't completely match the
value produced by the parser, and the makefile uses diff to print the
@@ -350,9 +349,8 @@ libxml2</p>
default one, and this will <em>automatically</em> get the correct
libraries linked with your program.</li>
</ul>
+ <p></p>
</li>
-
- <p></p>
<li><em>xmlDocDump() generates output on one line.</em>
<p>Libxml2 will not <strong>invent</strong> spaces in the content of a
document since <strong>all spaces in the content of a document are
@@ -370,8 +368,8 @@ libxml2</p>
href="http://xmlsoft.org/html/libxml-tree.html#xmlSaveFormatFile">xmlSaveFormatFile
()</a></li>
</ol>
+ <p></p>
</li>
- <p></p>
<li><em>Extra nodes in the document:</em>
<p><em>For an XML file as below:</em></p>
<pre>&lt;?xml version="1.0"?&gt;
@@ -445,8 +443,8 @@ pnode=pxmlDoc-&gt;children-&gt;children;</pre>
of <a href="http://svn.gnome.org/viewvc/libxml2/trunk/xmllint.c?view=markup">xmllint.c</a> and of the various testXXX.c test programs should
provide good examples of how to do things with the library.</li>
</ul>
+ <p></p>
</li>
- <p></p>
<li><em>What about C++ ?</em>
<p>libxml2 is written in pure C in order to allow easy reuse on a number
of platforms, including embedded systems. I don't intend to convert to
diff --git a/encoding.c b/encoding.c
index cdff6ae7..5e50c153 100644
--- a/encoding.c
+++ b/encoding.c
@@ -2629,7 +2629,6 @@ xmlCharEncOutFunc(xmlCharEncodingHandler *handler, xmlBufferPtr out,
int written;
int writtentot = 0;
int toconv;
- int output = 0;
if (handler == NULL) return(-1);
if (out == NULL) return(-1);
@@ -2682,8 +2681,6 @@ retry:
ret = -3;
}
- if (ret >= 0) output += ret;
-
/*
* Attempt to handle error cases
*/
diff --git a/fuzz/Makefile.am b/fuzz/Makefile.am
index 7d383470..6f487137 100644
--- a/fuzz/Makefile.am
+++ b/fuzz/Makefile.am
@@ -2,7 +2,7 @@ AUTOMAKE_OPTIONS = -Wno-syntax
EXTRA_PROGRAMS = genSeed html regexp schema uri xml xpath
check_PROGRAMS = testFuzzer
EXTRA_DIST = html.dict regexp.dict schema.dict xml.dict xpath.dict \
- seed/uri
+ seed/uri seed/regexp fuzz.h
CLEANFILES = $(EXTRA_PROGRAMS)
AM_CPPFLAGS = -I$(top_srcdir)/include
DEPENDENCIES = $(top_builddir)/libxml2.la
diff --git a/include/libxml/Makefile.am b/include/libxml/Makefile.am
index cf9297aa..328c1800 100644
--- a/include/libxml/Makefile.am
+++ b/include/libxml/Makefile.am
@@ -51,4 +51,4 @@ xmlinc_HEADERS = \
xmlsave.h \
schematron.h
-EXTRA_DIST = xmlversion.h.in
+EXTRA_DIST = xmlversion.h.in xmlwin32version.h.in
diff --git a/parser.c b/parser.c
index c9312fa4..255bd254 100644
--- a/parser.c
+++ b/parser.c
@@ -14672,7 +14672,8 @@ xmlInitParser(void) {
return;
#if defined(_WIN32) && (!defined(LIBXML_STATIC) || defined(LIBXML_STATIC_FOR_DLL))
- atexit(xmlCleanupParser);
+ if (xmlFree == free)
+ atexit(xmlCleanupParser);
#endif
#ifdef LIBXML_THREAD_ENABLED
diff --git a/xmlIO.c b/xmlIO.c
index 57312b97..f20c0fa0 100644
--- a/xmlIO.c
+++ b/xmlIO.c
@@ -3401,12 +3401,18 @@ xmlOutputBufferWrite(xmlOutputBufferPtr out, int len, const char *buf) {
out->error = XML_IO_ENCODER;
return(-1);
}
- nbchars = ret >= 0 ? ret : 0;
+ if (out->writecallback)
+ nbchars = xmlBufUse(out->conv);
+ else
+ nbchars = ret >= 0 ? ret : 0;
} else {
ret = xmlBufAdd(out->buffer, (const xmlChar *) buf, chunk);
if (ret != 0)
return(-1);
- nbchars = chunk;
+ if (out->writecallback)
+ nbchars = xmlBufUse(out->buffer);
+ else
+ nbchars = chunk;
}
buf += chunk;
len -= chunk;
@@ -3593,13 +3599,19 @@ xmlOutputBufferWriteEscape(xmlOutputBufferPtr out, const xmlChar *str,
out->error = XML_IO_ENCODER;
return(-1);
}
- nbchars = ret >= 0 ? ret : 0;
+ if (out->writecallback)
+ nbchars = xmlBufUse(out->conv);
+ else
+ nbchars = ret >= 0 ? ret : 0;
} else {
ret = escaping(xmlBufEnd(out->buffer), &chunk, str, &cons);
if ((ret < 0) || (chunk == 0)) /* chunk==0 => nothing done */
return(-1);
xmlBufAddLen(out->buffer, chunk);
- nbchars = chunk;
+ if (out->writecallback)
+ nbchars = xmlBufUse(out->buffer);
+ else
+ nbchars = chunk;
}
str += cons;
len -= cons;
diff --git a/xmlregexp.c b/xmlregexp.c
index 40dabb20..8d01c2ba 100644
--- a/xmlregexp.c
+++ b/xmlregexp.c
@@ -1892,6 +1892,12 @@ xmlFAReduceEpsilonTransitions(xmlRegParserCtxtPtr ctxt, int fromnr,
* then X and Y are semantically equivalent and X can be eliminated
* If X is the start state then make Y the start state, else replace the
* target of all transitions to X by transitions to Y.
+ *
+ * If X is a final state, skip it.
+ * Otherwise it would be necessary to manipulate counters for this case when
+ * eliminating state 2:
+ * State 1 has a transition with an atom to state 2.
+ * State 2 is final and has an epsilon transition to state 1.
*/
static void
xmlFAEliminateSimpleEpsilonTransitions(xmlRegParserCtxtPtr ctxt) {
@@ -1904,7 +1910,8 @@ xmlFAEliminateSimpleEpsilonTransitions(xmlRegParserCtxtPtr ctxt) {
continue;
if (state->nbTrans != 1)
continue;
- if (state->type == XML_REGEXP_UNREACH_STATE)
+ if (state->type == XML_REGEXP_UNREACH_STATE ||
+ state->type == XML_REGEXP_FINAL_STATE)
continue;
/* is the only transition out a basic transition */
if ((state->trans[0].atom == NULL) &&
diff --git a/xmlsave.c b/xmlsave.c
index 61a40459..489505f4 100644
--- a/xmlsave.c
+++ b/xmlsave.c
@@ -847,7 +847,7 @@ htmlNodeDumpOutputInternal(xmlSaveCtxtPtr ctxt, xmlNodePtr cur) {
static void
xmlNodeDumpOutputInternal(xmlSaveCtxtPtr ctxt, xmlNodePtr cur) {
int format = ctxt->format;
- xmlNodePtr tmp, root, unformattedNode = NULL;
+ xmlNodePtr tmp, root, unformattedNode = NULL, parent;
xmlAttrPtr attr;
xmlChar *start, *end;
xmlOutputBufferPtr buf;
@@ -856,6 +856,7 @@ xmlNodeDumpOutputInternal(xmlSaveCtxtPtr ctxt, xmlNodePtr cur) {
buf = ctxt->buf;
root = cur;
+ parent = cur->parent;
while (1) {
switch (cur->type) {
case XML_DOCUMENT_NODE:
@@ -868,7 +869,9 @@ xmlNodeDumpOutputInternal(xmlSaveCtxtPtr ctxt, xmlNodePtr cur) {
break;
case XML_DOCUMENT_FRAG_NODE:
- if (cur->children != NULL) {
+ /* Always validate cur->parent when descending. */
+ if ((cur->parent == parent) && (cur->children != NULL)) {
+ parent = cur;
cur = cur->children;
continue;
}
@@ -887,12 +890,23 @@ xmlNodeDumpOutputInternal(xmlSaveCtxtPtr ctxt, xmlNodePtr cur) {
break;
case XML_ELEMENT_NODE:
- if ((cur != root) && (ctxt->format == 1) && (xmlIndentTreeOutput))
+ if ((cur != root) && (ctxt->format == 1) &&
+ (xmlIndentTreeOutput))
xmlOutputBufferWrite(buf, ctxt->indent_size *
(ctxt->level > ctxt->indent_nr ?
ctxt->indent_nr : ctxt->level),
ctxt->indent);
+ /*
+ * Some users like lxml are known to pass nodes with a corrupted
+ * tree structure. Fall back to a recursive call to handle this
+ * case.
+ */
+ if ((cur->parent != parent) && (cur->children != NULL)) {
+ xmlNodeDumpOutputInternal(ctxt, cur);
+ break;
+ }
+
xmlOutputBufferWrite(buf, 1, "<");
if ((cur->ns != NULL) && (cur->ns->prefix != NULL)) {
xmlOutputBufferWriteString(buf, (const char *)cur->ns->prefix);
@@ -942,6 +956,7 @@ xmlNodeDumpOutputInternal(xmlSaveCtxtPtr ctxt, xmlNodePtr cur) {
xmlOutputBufferWrite(buf, 1, ">");
if (ctxt->format == 1) xmlOutputBufferWrite(buf, 1, "\n");
if (ctxt->level >= 0) ctxt->level++;
+ parent = cur;
cur = cur->children;
continue;
}
@@ -1058,13 +1073,9 @@ xmlNodeDumpOutputInternal(xmlSaveCtxtPtr ctxt, xmlNodePtr cur) {
break;
}
- /*
- * The parent should never be NULL here but we want to handle
- * corrupted documents gracefully.
- */
- if (cur->parent == NULL)
- return;
- cur = cur->parent;
+ cur = parent;
+ /* cur->parent was validated when descending. */
+ parent = cur->parent;
if (cur->type == XML_ELEMENT_NODE) {
if (ctxt->level > 0) ctxt->level--;
diff --git a/xpath.c b/xpath.c
index 7497ba07..1aa2f1ab 100644
--- a/xpath.c
+++ b/xpath.c
@@ -10983,7 +10983,7 @@ xmlXPathCompileExpr(xmlXPathParserContextPtr ctxt, int sort) {
}
if (xpctxt != NULL)
- xpctxt->depth -= 1;
+ xpctxt->depth -= 10;
}
/**