Uploaded image for project: 'XalanJ2'
  1. XalanJ2
  2. XALANJ-2030

Relational expression yields wrong result for right-hand param operand

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Resolved
    • Major
    • Resolution: Duplicate
    • 2.6
    • 2.7
    • XSLTC
    • None

    Description

      The bug can be demonstrated with the following stylesheet:

      <?xml version="1.0"?>
      <!-- bug1.xsl -->
      <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

      <xsl:param name="six" select="/input/@six"/>

      <xsl:template match="/">
      <result>
      <xsl:if test="5 < $six">
      okay 5 lt $six
      </xsl:if>
      <xsl:if test="7 < $six">
      fail 7 lt $six
      </xsl:if>
      <xsl:if test="$six > 5">
      okay $six gt 5
      </xsl:if>
      <xsl:if test="$six > 7">
      fail $six gt 7
      </xsl:if>
      </result>
      </xsl:template>
      </xsl:stylesheet>

      Given the input:

      <?xml version="1.0"?>
      <!-- in1.xml -->
      <input six="6"/>

      The correct result produced by the Xalan interpreter is:

      xalan -in in1.xml -xsl bug1.xsl
      <result>
      okay 5 lt $six
      okay $six gt 5
      </result>

      XSLTC 2.6.0 produces a wrong result where 7 < $six evaluates as true:

      xalan -in in1.xml -xsl bug1.xsl -xsltc -v
      >>>>>>> Xalan Version Xalan Java 2.6.0, <<<<<<<
      <result>
      fail 7 lt $six
      okay $six gt 5
      </result>

      The bug is introduced because for simplifying the comparison the operands are swapped without adapting non-commuting operators accordingly. Here is the patch to be applied in org/apache/xalan/xsltc/runtime/BasisLibrary.java:

      — BasisLibrary.java.orig 2004-02-27 20:45:28.000000000 +0100
      +++ BasisLibrary.java 2004-12-21 10:48:29.644000000 +0100
      @@ -741,8 +741,16 @@

      if (hasSimpleType(left) ||
      left instanceof DOM && right instanceof DTMAxisIterator)

      { - // swap operands + // swap operands and conjugate non-commuting operator final Object temp = right; right = left; left = temp; + if (op == GT) + op = LE; + else if (op == LT) + op = GE; + else if (op == GE) + op = LT; + else if (op == LE) + op = GT; }

      if (left instanceof DOM) {

      This particular bug manifests itself only under very specific circumstances. It only occurs if a node-set is passed as parameter (<xsl:param> or <xsl:with-param>) and used as right-hand-side operator in a relational expression.

      If one is aware of it's presence, it can be avoid be any of these variations:

      *) Use variable instead of parameter:
      <xsl:variable name="six" select="/input/@six"/>
      *) Explicit conversion to number in assignment:
      <xsl:param name="six" select="number(/input/@six)"/>
      *) Explicit conversion to number in expression:
      <xsl:if test="7 < number($six)">
      *) Move parameter to left-hand-side:
      <xsl:if test="$six >= 7">

      PS What I didn't understand is the difference between xsl:param and xsl:variable. Why does Param.typeCheck cast _select from node-set to reference?

      Attachments

        Issue Links

          Activity

            People

              Unassigned Unassigned
              anathaniel@apache.org Alfred Nathaniel
              Votes:
              0 Vote for this issue
              Watchers:
              0 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved: