133 lines
4.5 KiB
Diff
133 lines
4.5 KiB
Diff
From 08b62c25871b38d5d573515ca8a065b4b8f64f6b Mon Sep 17 00:00:00 2001
|
|
From: Nick Wellnhofer <wellnhofer@aevum.de>
|
|
Date: Wed, 20 Feb 2019 13:24:37 +0100
|
|
Subject: [PATCH 31/33] Always set context node before calling XPath iterators
|
|
MIME-Version: 1.0
|
|
Content-Type: text/plain; charset=UTF-8
|
|
Content-Transfer-Encoding: 8bit
|
|
|
|
The xmlXPathNext* iterators rely on the XPath context node being set to
|
|
the start node of the iteration. Some parts of the code base like the
|
|
xsl:key functions also leave the context node in an unspecified state.
|
|
Make sure that the context node is reset before invoking the XPath
|
|
iterators. Also backup and restore the context node in
|
|
xsltNumberFormatGetMultipleLevel for good measure.
|
|
|
|
This bug could also lead to type confusion and invalid reads in
|
|
connection with namespace nodes.
|
|
|
|
Fixes #13. Also see the Chromium bug report:
|
|
|
|
https://bugs.chromium.org/p/chromium/issues/detail?id=930663
|
|
|
|
Thanks to Nicolas Grégoire for the report.
|
|
---
|
|
libxslt/numbers.c | 31 ++++++++++++++++++++-----------
|
|
tests/docs/bug-218.xml | 1 +
|
|
tests/general/bug-218.out | 2 ++
|
|
tests/general/bug-218.xsl | 8 ++++++++
|
|
4 files changed, 31 insertions(+), 11 deletions(-)
|
|
create mode 100644 tests/docs/bug-218.xml
|
|
create mode 100644 tests/general/bug-218.out
|
|
create mode 100644 tests/general/bug-218.xsl
|
|
|
|
diff --git a/libxslt/numbers.c b/libxslt/numbers.c
|
|
index 0d34740..89e1f66 100644
|
|
--- a/libxslt/numbers.c
|
|
+++ b/libxslt/numbers.c
|
|
@@ -646,42 +646,51 @@ xsltNumberFormatGetMultipleLevel(xsltTransformContextPtr context,
|
|
{
|
|
int amount = 0;
|
|
int cnt;
|
|
+ xmlNodePtr oldCtxtNode;
|
|
xmlNodePtr ancestor;
|
|
xmlNodePtr preceding;
|
|
xmlXPathParserContextPtr parser;
|
|
|
|
- context->xpathCtxt->node = node;
|
|
+ oldCtxtNode = context->xpathCtxt->node;
|
|
parser = xmlXPathNewParserContext(NULL, context->xpathCtxt);
|
|
if (parser) {
|
|
/* ancestor-or-self::*[count] */
|
|
- for (ancestor = node;
|
|
- (ancestor != NULL) && (ancestor->type != XML_DOCUMENT_NODE);
|
|
- ancestor = xmlXPathNextAncestor(parser, ancestor)) {
|
|
-
|
|
+ ancestor = node;
|
|
+ while ((ancestor != NULL) && (ancestor->type != XML_DOCUMENT_NODE)) {
|
|
if ((fromPat != NULL) &&
|
|
xsltTestCompMatchList(context, ancestor, fromPat))
|
|
break; /* for */
|
|
|
|
+ /*
|
|
+ * The xmlXPathNext* iterators require that the context node is
|
|
+ * set to the start node. Calls to xsltTestCompMatch* may also
|
|
+ * leave the context node in an undefined state, so make sure
|
|
+ * that the context node is reset before each iterator invocation.
|
|
+ */
|
|
+
|
|
if (xsltTestCompMatchCount(context, ancestor, countPat, node)) {
|
|
/* count(preceding-sibling::*) */
|
|
cnt = 1;
|
|
- for (preceding =
|
|
- xmlXPathNextPrecedingSibling(parser, ancestor);
|
|
- preceding != NULL;
|
|
- preceding =
|
|
- xmlXPathNextPrecedingSibling(parser, preceding)) {
|
|
-
|
|
+ context->xpathCtxt->node = ancestor;
|
|
+ preceding = xmlXPathNextPrecedingSibling(parser, ancestor);
|
|
+ while (preceding != NULL) {
|
|
if (xsltTestCompMatchCount(context, preceding, countPat,
|
|
node))
|
|
cnt++;
|
|
+ context->xpathCtxt->node = ancestor;
|
|
+ preceding =
|
|
+ xmlXPathNextPrecedingSibling(parser, preceding);
|
|
}
|
|
array[amount++] = (double)cnt;
|
|
if (amount >= max)
|
|
break; /* for */
|
|
}
|
|
+ context->xpathCtxt->node = node;
|
|
+ ancestor = xmlXPathNextAncestor(parser, ancestor);
|
|
}
|
|
xmlXPathFreeParserContext(parser);
|
|
}
|
|
+ context->xpathCtxt->node = oldCtxtNode;
|
|
return amount;
|
|
}
|
|
|
|
diff --git a/tests/docs/bug-218.xml b/tests/docs/bug-218.xml
|
|
new file mode 100644
|
|
index 0000000..3806547
|
|
--- /dev/null
|
|
+++ b/tests/docs/bug-218.xml
|
|
@@ -0,0 +1 @@
|
|
+<top xmlns:ns1="foo"/>
|
|
diff --git a/tests/general/bug-218.out b/tests/general/bug-218.out
|
|
new file mode 100644
|
|
index 0000000..832a29e
|
|
--- /dev/null
|
|
+++ b/tests/general/bug-218.out
|
|
@@ -0,0 +1,2 @@
|
|
+<?xml version="1.0"?>
|
|
+1
|
|
diff --git a/tests/general/bug-218.xsl b/tests/general/bug-218.xsl
|
|
new file mode 100644
|
|
index 0000000..fdbb7b1
|
|
--- /dev/null
|
|
+++ b/tests/general/bug-218.xsl
|
|
@@ -0,0 +1,8 @@
|
|
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
|
|
+ <xsl:key name="aaa" match="/bbb" use="./ccc"/>
|
|
+ <xsl:template match="*">
|
|
+ <xsl:for-each select="namespace::*[position()=2]">
|
|
+ <xsl:number from="key('e','f')"/>
|
|
+ </xsl:for-each>
|
|
+ </xsl:template>
|
|
+</xsl:stylesheet>
|
|
--
|
|
1.8.3.1
|
|
|