JezK
Edit File: 0009-Fix-certain-patterns-with-predicates.patch
From cd40951e8e8a00e3ea022c2956d352bc131a54ba Mon Sep 17 00:00:00 2001 From: Nick Wellnhofer <wellnhofer@aevum.de> Date: Sun, 4 Aug 2013 22:59:26 +0200 Subject: [PATCH 09/14] Fix certain patterns with predicates The optimization for predicates in patterns only supports XSLT_OP_ELEM and XSLT_OP_ALL. This commit makes predicates on other ops fall back to the slow direct matching code path. Fixes bugs #531685 and #538580. --- libxslt/pattern.c | 18 ++++++++++++------ tests/docs/Makefile.am | 2 ++ tests/docs/bug-181.xml | 4 ++++ tests/docs/bug-182.xml | 4 ++++ tests/general/Makefile.am | 2 ++ tests/general/bug-181.out | 5 +++++ tests/general/bug-181.xsl | 13 +++++++++++++ tests/general/bug-182.out | 2 ++ tests/general/bug-182.xsl | 19 +++++++++++++++++++ 9 files changed, 63 insertions(+), 6 deletions(-) create mode 100644 tests/docs/bug-181.xml create mode 100644 tests/docs/bug-182.xml create mode 100644 tests/general/bug-181.out create mode 100644 tests/general/bug-181.xsl create mode 100644 tests/general/bug-182.out create mode 100644 tests/general/bug-182.xsl diff --git a/libxslt/pattern.c b/libxslt/pattern.c index 058917a..a97726c 100644 --- a/libxslt/pattern.c +++ b/libxslt/pattern.c @@ -451,11 +451,14 @@ xsltReverseCompMatch(xsltParserContextPtr ctxt, xsltCompMatchPtr comp) { xsltCompMatchAdd(ctxt, comp, XSLT_OP_END, NULL, NULL, 0); /* - * detect consecutive XSLT_OP_PREDICATE indicating a direct - * matching should be done. + * Detect consecutive XSLT_OP_PREDICATE and predicates on ops which + * haven't been optimized yet indicating a direct matching should be done. */ for (i = 0;i < comp->nbStep - 1;i++) { - if ((comp->steps[i].op == XSLT_OP_PREDICATE) && + xsltOp op = comp->steps[i].op; + + if ((op != XSLT_OP_ELEM) && + (op != XSLT_OP_ALL) && (comp->steps[i + 1].op == XSLT_OP_PREDICATE)) { comp->direct = 1; @@ -655,8 +658,10 @@ xsltTestPredicateMatch(xsltTransformContextPtr ctxt, xsltCompMatchPtr comp, isRVT = 0; /* - * Depending on the last selection, one may need to - * recompute contextSize and proximityPosition. + * Recompute contextSize and proximityPosition. + * + * TODO: Make this work for additional ops. Currently, only XSLT_OP_ELEM + * and XSLT_OP_ALL are supported. */ oldCS = ctxt->xpathCtxt->contextSize; oldCP = ctxt->xpathCtxt->proximityPosition; @@ -1128,7 +1133,8 @@ restart: break; case XSLT_OP_PREDICATE: { /* - * when there is cascading XSLT_OP_PREDICATE, then use a + * When there is cascading XSLT_OP_PREDICATE or a predicate + * after an op which hasn't been optimized yet, then use a * direct computation approach. It's not done directly * at the beginning of the routine to filter out as much * as possible this costly computation. diff --git a/tests/docs/Makefile.am b/tests/docs/Makefile.am index c5dad4c..e3a4aef 100644 --- a/tests/docs/Makefile.am +++ b/tests/docs/Makefile.am @@ -179,6 +179,8 @@ EXTRA_DIST = \ bug-178.xml \ bug-179.xml \ bug-180.xml \ + bug-181.xml \ + bug-182.xml \ character.xml \ array.xml \ items.xml diff --git a/tests/docs/bug-181.xml b/tests/docs/bug-181.xml new file mode 100644 index 0000000..285b69a --- /dev/null +++ b/tests/docs/bug-181.xml @@ -0,0 +1,4 @@ +<Urmel> + <E>1. zwei <F>drei</F> zwei eins</E> + <E a="b">2. zwei <F>drei</F> zwei eins</E> +</Urmel> diff --git a/tests/docs/bug-182.xml b/tests/docs/bug-182.xml new file mode 100644 index 0000000..02b378d --- /dev/null +++ b/tests/docs/bug-182.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<root> +<body><b> b 1 </b> text 1 <b> b 2 </b> text 2 </body> +</root> diff --git a/tests/general/Makefile.am b/tests/general/Makefile.am index 0c2ef30..4802a6b 100644 --- a/tests/general/Makefile.am +++ b/tests/general/Makefile.am @@ -188,6 +188,8 @@ EXTRA_DIST = \ bug-178.out bug-178.xsl \ bug-179.out bug-179.xsl \ bug-180.out bug-180.xsl bug-180.err \ + bug-181.out bug-181.xsl \ + bug-182.out bug-182.xsl \ character.out character.xsl \ character2.out character2.xsl \ itemschoose.out itemschoose.xsl \ diff --git a/tests/general/bug-181.out b/tests/general/bug-181.out new file mode 100644 index 0000000..730387a --- /dev/null +++ b/tests/general/bug-181.out @@ -0,0 +1,5 @@ +<?xml version="1.0"?> +<Urmel> + <E>1. * zwei <F>drei</F> zwei eins</E> + <E a="b">2. * zwei <F>drei</F> zwei eins</E> +</Urmel> diff --git a/tests/general/bug-181.xsl b/tests/general/bug-181.xsl new file mode 100644 index 0000000..0c4de71 --- /dev/null +++ b/tests/general/bug-181.xsl @@ -0,0 +1,13 @@ +<xsl:transform version="1.0" + xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> + <xsl:template match="E/text()[ 1 ]"> + <xsl:value-of select="substring-before( . , ' ')"/> + <xsl:text> * </xsl:text> + <xsl:value-of select="substring-after( . , ' ')"/> + </xsl:template> + <xsl:template match="@*|node()"> + <xsl:copy> + <xsl:apply-templates select="@*|node()"/> + </xsl:copy> + </xsl:template> +</xsl:transform> diff --git a/tests/general/bug-182.out b/tests/general/bug-182.out new file mode 100644 index 0000000..93ab15e --- /dev/null +++ b/tests/general/bug-182.out @@ -0,0 +1,2 @@ +<?xml version="1.0"?> +<body><p>b[2]: b 2 </p><p>text()[2]: text 2 </p></body> diff --git a/tests/general/bug-182.xsl b/tests/general/bug-182.xsl new file mode 100644 index 0000000..ecce187 --- /dev/null +++ b/tests/general/bug-182.xsl @@ -0,0 +1,19 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> + +<xsl:template match="node()"/> + +<xsl:template match="text()[2]"> + <p>text()[2]: <xsl:value-of select="."/></p> +</xsl:template> +<xsl:template match="b[2]"> + <p>b[2]: <xsl:value-of select="."/></p> +</xsl:template> + +<xsl:template match="/"> + <body> + <xsl:apply-templates select="/root/body/node()"/> + </body> +</xsl:template> + +</xsl:stylesheet> -- 1.8.4.1