summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Wellnhofer <wellnhofer@aevum.de>2018-11-21 17:12:17 +0100
committerNick Wellnhofer <wellnhofer@aevum.de>2018-11-21 17:37:19 +0100
commita846514a159a2524266b57d8aae47b66572d0b0a (patch)
tree8e83c431148a7b752d3d29b9b306421dfd9760c6
parent5e16672db1188accbde737f0add01213ffed107e (diff)
downloadlibxslt-1.1.33-rc2.tar.gz
Don't cache direct evaluation of patterns with variablesv1.1.33-rc2
The slow pattern matching path in xsltTestCompMatchDirect caches the result of evaluating the pattern. But this can't be done if the pattern contains variables which could evaluate to different values. Only enable the cache for patterns like template matches that don't allow variable references. Don't use the cache for "count" and "from" patterns in xsl:number. A more fine-grained approach would be nice, but most effort should be spent on eliminating the slow path completely. Thanks to Martin Honnen for the report. Fixes #6.
-rw-r--r--libxslt/pattern.c5
-rw-r--r--tests/docs/bug-214.xml6
-rw-r--r--tests/general/bug-214.out6
-rw-r--r--tests/general/bug-214.xsl25
4 files changed, 41 insertions, 1 deletions
diff --git a/libxslt/pattern.c b/libxslt/pattern.c
index 07f11f9b..7d660192 100644
--- a/libxslt/pattern.c
+++ b/libxslt/pattern.c
@@ -113,6 +113,7 @@ struct _xsltCompMatch {
xmlNsPtr *nsList; /* the namespaces in scope */
int nsNr; /* the number of namespaces in scope */
xsltStepOpPtr steps; /* ops for computation */
+ int novar; /* doesn't contain variables */
};
typedef struct _xsltParserContext xsltParserContext;
@@ -594,7 +595,8 @@ xsltTestCompMatchDirect(xsltTransformContextPtr ctxt, xsltCompMatchPtr comp,
}
ix = 0;
- if ((parent == NULL) || (node->doc == NULL) || isRVT)
+ if ((parent == NULL) || (node->doc == NULL) || isRVT ||
+ (comp->novar == 0))
nocache = 1;
if (nocache == 0) {
@@ -1970,6 +1972,7 @@ xsltCompilePatternInternal(const xmlChar *pattern, xmlDocPtr doc,
j++;
}
element->nsNr = j;
+ element->novar = novar;
#ifdef WITH_XSLT_DEBUG_PATTERN
diff --git a/tests/docs/bug-214.xml b/tests/docs/bug-214.xml
new file mode 100644
index 00000000..196b8025
--- /dev/null
+++ b/tests/docs/bug-214.xml
@@ -0,0 +1,6 @@
+<root>
+ <element type="a"/>
+ <element type="b"/>
+ <element type="a"/>
+</root>
+
diff --git a/tests/general/bug-214.out b/tests/general/bug-214.out
new file mode 100644
index 00000000..e51e7097
--- /dev/null
+++ b/tests/general/bug-214.out
@@ -0,0 +1,6 @@
+<?xml version="1.0"?>
+<root>
+ <element type="a" pos="1"/>
+ <element type="b" pos="1"/>
+ <element type="a" pos="2"/>
+</root>
diff --git a/tests/general/bug-214.xsl b/tests/general/bug-214.xsl
new file mode 100644
index 00000000..52243113
--- /dev/null
+++ b/tests/general/bug-214.xsl
@@ -0,0 +1,25 @@
+<xsl:stylesheet
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ version="1.0">
+
+ <xsl:template match="@* | node()">
+ <xsl:copy>
+ <xsl:apply-templates select="@* | node()"/>
+ </xsl:copy>
+ </xsl:template>
+
+ <xsl:template match="*[@type]">
+ <xsl:copy>
+ <xsl:variable name="type" select="@type"/>
+ <xsl:variable name="pos">
+ <xsl:number count="node()[@type = $type]"/>
+ </xsl:variable>
+ <xsl:apply-templates select="@*"/>
+ <xsl:attribute name="pos">
+ <xsl:value-of select="$pos"/>
+ </xsl:attribute>
+ <xsl:apply-templates/>
+ </xsl:copy>
+ </xsl:template>
+
+</xsl:stylesheet>