diff options
author | Nick Wellnhofer <wellnhofer@aevum.de> | 2018-11-21 17:12:17 +0100 |
---|---|---|
committer | Nick Wellnhofer <wellnhofer@aevum.de> | 2018-11-21 17:37:19 +0100 |
commit | a846514a159a2524266b57d8aae47b66572d0b0a (patch) | |
tree | 8e83c431148a7b752d3d29b9b306421dfd9760c6 | |
parent | 5e16672db1188accbde737f0add01213ffed107e (diff) | |
download | libxslt-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.c | 5 | ||||
-rw-r--r-- | tests/docs/bug-214.xml | 6 | ||||
-rw-r--r-- | tests/general/bug-214.out | 6 | ||||
-rw-r--r-- | tests/general/bug-214.xsl | 25 |
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> |