mirror of
				https://gitlab.gnome.org/GNOME/libxslt
				synced 2025-11-04 00:53:12 +03:00 
			
		
		
		
	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.
This commit is contained in:
		@@ -451,11 +451,14 @@ xsltReverseCompMatch(xsltParserContextPtr ctxt, xsltCompMatchPtr comp) {
 | 
				
			|||||||
    xsltCompMatchAdd(ctxt, comp, XSLT_OP_END, NULL, NULL, 0);
 | 
					    xsltCompMatchAdd(ctxt, comp, XSLT_OP_END, NULL, NULL, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /*
 | 
					    /*
 | 
				
			||||||
     * detect consecutive XSLT_OP_PREDICATE indicating a direct
 | 
					     * Detect consecutive XSLT_OP_PREDICATE and predicates on ops which
 | 
				
			||||||
     * matching should be done.
 | 
					     * haven't been optimized yet indicating a direct matching should be done.
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    for (i = 0;i < comp->nbStep - 1;i++) {
 | 
					    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->steps[i + 1].op == XSLT_OP_PREDICATE)) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	    comp->direct = 1;
 | 
						    comp->direct = 1;
 | 
				
			||||||
@@ -655,8 +658,10 @@ xsltTestPredicateMatch(xsltTransformContextPtr ctxt, xsltCompMatchPtr comp,
 | 
				
			|||||||
        isRVT = 0;
 | 
					        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;
 | 
					    oldCS = ctxt->xpathCtxt->contextSize;
 | 
				
			||||||
    oldCP = ctxt->xpathCtxt->proximityPosition;
 | 
					    oldCP = ctxt->xpathCtxt->proximityPosition;
 | 
				
			||||||
@@ -1128,7 +1133,8 @@ restart:
 | 
				
			|||||||
		break;
 | 
							break;
 | 
				
			||||||
	    case XSLT_OP_PREDICATE: {
 | 
						    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
 | 
							 * direct computation approach. It's not done directly
 | 
				
			||||||
		 * at the beginning of the routine to filter out as much
 | 
							 * at the beginning of the routine to filter out as much
 | 
				
			||||||
		 * as possible this costly computation.
 | 
							 * as possible this costly computation.
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -179,6 +179,8 @@ EXTRA_DIST =	\
 | 
				
			|||||||
	bug-178.xml \
 | 
						bug-178.xml \
 | 
				
			||||||
	bug-179.xml \
 | 
						bug-179.xml \
 | 
				
			||||||
	bug-180.xml \
 | 
						bug-180.xml \
 | 
				
			||||||
 | 
						bug-181.xml \
 | 
				
			||||||
 | 
						bug-182.xml \
 | 
				
			||||||
	character.xml \
 | 
						character.xml \
 | 
				
			||||||
	array.xml \
 | 
						array.xml \
 | 
				
			||||||
	items.xml
 | 
						items.xml
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										4
									
								
								tests/docs/bug-181.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								tests/docs/bug-181.xml
									
									
									
									
									
										Normal file
									
								
							@@ -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>
 | 
				
			||||||
							
								
								
									
										4
									
								
								tests/docs/bug-182.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								tests/docs/bug-182.xml
									
									
									
									
									
										Normal file
									
								
							@@ -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>
 | 
				
			||||||
@@ -188,6 +188,8 @@ EXTRA_DIST = \
 | 
				
			|||||||
    bug-178.out bug-178.xsl \
 | 
					    bug-178.out bug-178.xsl \
 | 
				
			||||||
    bug-179.out bug-179.xsl \
 | 
					    bug-179.out bug-179.xsl \
 | 
				
			||||||
    bug-180.out bug-180.xsl bug-180.err \
 | 
					    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 \
 | 
					    character.out character.xsl \
 | 
				
			||||||
    character2.out character2.xsl \
 | 
					    character2.out character2.xsl \
 | 
				
			||||||
    itemschoose.out itemschoose.xsl \
 | 
					    itemschoose.out itemschoose.xsl \
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										5
									
								
								tests/general/bug-181.out
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								tests/general/bug-181.out
									
									
									
									
									
										Normal file
									
								
							@@ -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>
 | 
				
			||||||
							
								
								
									
										13
									
								
								tests/general/bug-181.xsl
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								tests/general/bug-181.xsl
									
									
									
									
									
										Normal file
									
								
							@@ -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>
 | 
				
			||||||
							
								
								
									
										2
									
								
								tests/general/bug-182.out
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								tests/general/bug-182.out
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,2 @@
 | 
				
			|||||||
 | 
					<?xml version="1.0"?>
 | 
				
			||||||
 | 
					<body><p>b[2]:  b 2 </p><p>text()[2]:  text 2 </p></body>
 | 
				
			||||||
							
								
								
									
										19
									
								
								tests/general/bug-182.xsl
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								tests/general/bug-182.xsl
									
									
									
									
									
										Normal file
									
								
							@@ -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>
 | 
				
			||||||
		Reference in New Issue
	
	Block a user