From cd40951e8e8a00e3ea022c2956d352bc131a54ba Mon Sep 17 00:00:00 2001 From: Nick Wellnhofer 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 @@ + + 1. zwei drei zwei eins + 2. zwei drei zwei eins + 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 @@ + + + b 1 text 1 b 2 text 2 + 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 @@ + + + 1. * zwei drei zwei eins + 2. * zwei drei zwei eins + 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 @@ + + + + * + + + + + + + + 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 @@ + +

b[2]: b 2

text()[2]: text 2

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 @@ + + + + + + +

text()[2]:

+
+ +

b[2]:

+
+ + + + + + + +
-- 1.8.4.1