XalanJ2
  1. XalanJ2
  2. XALANJ-2424

set:distinct() over attribute list breaks XSLTC throwing HIERARCHY_REQUEST_ERR

    Details

    • Type: Bug Bug
    • Status: Resolved
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 2.7.1, 2.7
    • Component/s: XSLTC
    • Labels:
      None
    • Environment:
      Linux, Sun java 1.6
    • Fix priority:
      fp3

      Description

      If you do set:distinct over attribute list, XSLTC-compiled translet throws HIERARCHY_REQUEST_ERR exception.
      Exception is localised to point where set:distinct is called, even if it is assigned into a variable.

      Test case:
      <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:set="http://exslt.org/sets" version="1.0">
      <xsl:output method="html" />
      <xsl:template match="/">
      <xsl:variable name="attrs" select="set:distinct(source/element/@attr)" />
      <html><body>
      <xsl:for-each select="$attrs">
      <xsl:value-of select="." />
      </xsl:for-each>
      </body></html>
      </xsl:template>
      </xsl:stylesheet>

      With xml
      <source>
      <element attr="val1" name="foobar" />
      <element attr="val2" name="bar" />
      <element attr="val2" name="baz" />
      <element attr="val3" name="baz" />
      </source>

      that will cause an Exception to be thrown when variable is assigned.

      My unedicated guess is that it tries to apply-templates over selected nodes into document in place where set:distinct is computed. This happens, as I see for different partially-serialized document, before variable's enclosing element is closed. I've disassembled the stylesheet but didn't understand much from there, it goes like this:
      // 30 66:invokeinterface #110 <Method org.w3c.dom.NodeList DOM.makeNodeList(DTMAxisIterator)>
      // 31 71:invokestatic #116 <Method org.w3c.dom.NodeList ExsltSets.distinct(org.w3c.dom.NodeList)>
      // 32 74:aload_0
      // 33 75:aload_1
      // 34 76:invokestatic #122 <Method DTMAxisIterator BasisLibrary.nodeList2Iterator(org.w3c.dom.NodeList, org.apache.xalan.xsltc.Translet, DOM)>
      // 35 79:new #126 <Class CachedNodeListIterator>
      // 36 82:dup_x1
      // 37 83:swap
      // 38 84:invokespecial #127 <Method void CachedNodeListIterator(DTMAxisIterator)>
      // 39 87:iload 4
      // 40 89:invokeinterface #41 <Method DTMAxisIterator DTMAxisIterator.setStartNode(int)>
      // 41 94:astore 9
      // 42 96:aload_3
      // 43 97:ldc1 #129 <String "html">
      // 44 99:dup2
      // 45 100:invokeinterface #14 <Method void SerializationHandler.startElement(String)>

      P.S. If said variable is located in prologue (not inside any xsl:template) the bug persists.

      1. Process.jad
        14 kB
        Ilya Kasnacheev
      2. xml1.xml
        0.2 kB
        Ilya Kasnacheev
      3. xsl1.xsl
        0.4 kB
        Ilya Kasnacheev

        Issue Links

          Activity

          Ilya Kasnacheev created issue -
          Hide
          Ilya Kasnacheev added a comment -

          This is XSL file where bug is reproduced.

          Show
          Ilya Kasnacheev added a comment - This is XSL file where bug is reproduced.
          Ilya Kasnacheev made changes -
          Field Original Value New Value
          Attachment xsl1.xsl [ 12374024 ]
          Hide
          Ilya Kasnacheev added a comment -

          XML file to apply bug-ridden stylesheet to.

          Show
          Ilya Kasnacheev added a comment - XML file to apply bug-ridden stylesheet to.
          Ilya Kasnacheev made changes -
          Attachment xml1.xml [ 12374025 ]
          Hide
          Ilya Kasnacheev added a comment -

          This is the stylesheet cdompiled with xalan 2.7.1 and disassembled by jad.

          Show
          Ilya Kasnacheev added a comment - This is the stylesheet cdompiled with xalan 2.7.1 and disassembled by jad.
          Ilya Kasnacheev made changes -
          Attachment Process.jad [ 12374026 ]
          Hide
          Ilya Kasnacheev added a comment -

          Clean up, more info.

          Show
          Ilya Kasnacheev added a comment - Clean up, more info.
          Ilya Kasnacheev made changes -
          Description If you do set:distinct over attribute list, XSLTC-compiled translet throws HIERARCHY_REQUEST_ERR exception.
          Exception is localised to point where set:distinct is called, even if it is assigned into a variable.

          Test case:
          <code><pre><tt><xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:set="http://exslt.org/sets" version="1.0">
                  <xsl:output method="html" />
                  <xsl:template match="/">
                          <xsl:variable name="attrs" select="set:distinct(source/element/@attr)" />
            <html><body>
                          <xsl:for-each select="$attrs">
                                  <xsl:value-of select="." />
                          </xsl:for-each>
                          </body></html>
                  </xsl:template>
          </xsl:stylesheet></tt></pre></code>

          With xml
          <code><pre><tt><source>
                  <element attr="val1" name="foobar" />
                  <element attr="val2" name="bar" />
                  <element attr="val2" name="baz" />
                  <element attr="val3" name="baz" />
          </source></tt></pre></code>

          that will cause an Exception to be thrown when variable is assigned.

          My unedicated guess is that it tries to apply-templates over selected nodes into document in place where set:distinct is computed. This happens, as I see for different partially-serialized document, before variable's enclosing element is closed. I've disassembled the stylesheet but didn't understand much from there, it goes like this:
          <code><pre><tt> // 30 66:invokeinterface #110 <Method org.w3c.dom.NodeList DOM.makeNodeList(DTMAxisIterator)>
              // 31 71:invokestatic #116 <Method org.w3c.dom.NodeList ExsltSets.distinct(org.w3c.dom.NodeList)>
              // 32 74:aload_0
              // 33 75:aload_1
              // 34 76:invokestatic #122 <Method DTMAxisIterator BasisLibrary.nodeList2Iterator(org.w3c.dom.NodeList, org.apache.xalan.xsltc.Translet, DOM)>
              // 35 79:new #126 <Class CachedNodeListIterator>
              // 36 82:dup_x1
              // 37 83:swap
              // 38 84:invokespecial #127 <Method void CachedNodeListIterator(DTMAxisIterator)>
              // 39 87:iload 4
              // 40 89:invokeinterface #41 <Method DTMAxisIterator DTMAxisIterator.setStartNode(int)>
              // 41 94:astore 9
              // 42 96:aload_3
              // 43 97:ldc1 #129 <String "html">
              // 44 99:dup2
              // 45 100:invokeinterface #14 <Method void SerializationHandler.startElement(String)></tt></pre></code>
          If you do set:distinct over attribute list, XSLTC-compiled translet throws HIERARCHY_REQUEST_ERR exception.
          Exception is localised to point where set:distinct is called, even if it is assigned into a variable.

          Test case:
          <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:set="http://exslt.org/sets" version="1.0">
                  <xsl:output method="html" />
                  <xsl:template match="/">
                          <xsl:variable name="attrs" select="set:distinct(source/element/@attr)" />
            <html><body>
                          <xsl:for-each select="$attrs">
                                  <xsl:value-of select="." />
                          </xsl:for-each>
                          </body></html>
                  </xsl:template>
          </xsl:stylesheet>

          With xml
          <source>
                  <element attr="val1" name="foobar" />
                  <element attr="val2" name="bar" />
                  <element attr="val2" name="baz" />
                  <element attr="val3" name="baz" />
          </source>

          that will cause an Exception to be thrown when variable is assigned.

          My unedicated guess is that it tries to apply-templates over selected nodes into document in place where set:distinct is computed. This happens, as I see for different partially-serialized document, before variable's enclosing element is closed. I've disassembled the stylesheet but didn't understand much from there, it goes like this:
              // 30 66:invokeinterface #110 <Method org.w3c.dom.NodeList DOM.makeNodeList(DTMAxisIterator)>
              // 31 71:invokestatic #116 <Method org.w3c.dom.NodeList ExsltSets.distinct(org.w3c.dom.NodeList)>
              // 32 74:aload_0
              // 33 75:aload_1
              // 34 76:invokestatic #122 <Method DTMAxisIterator BasisLibrary.nodeList2Iterator(org.w3c.dom.NodeList, org.apache.xalan.xsltc.Translet, DOM)>
              // 35 79:new #126 <Class CachedNodeListIterator>
              // 36 82:dup_x1
              // 37 83:swap
              // 38 84:invokespecial #127 <Method void CachedNodeListIterator(DTMAxisIterator)>
              // 39 87:iload 4
              // 40 89:invokeinterface #41 <Method DTMAxisIterator DTMAxisIterator.setStartNode(int)>
              // 41 94:astore 9
              // 42 96:aload_3
              // 43 97:ldc1 #129 <String "html">
              // 44 99:dup2
              // 45 100:invokeinterface #14 <Method void SerializationHandler.startElement(String)>

          P.S. If said variable is located in prologue (not inside any xsl:template) the bug persists.
          Hide
          Ilya Kasnacheev added a comment -

          BasisLibrary::nodeList2Iterator does seriously 'not smart' thing:
          It attempts to appendChild() an attribute node into DocumentElement.
          That's an obvious bag, but I'll now go farther and try to understand why nodeList2Iterator is called in the first place: simply listing elements don't cause that.

          Show
          Ilya Kasnacheev added a comment - BasisLibrary::nodeList2Iterator does seriously 'not smart' thing: It attempts to appendChild() an attribute node into DocumentElement. That's an obvious bag, but I'll now go farther and try to understand why nodeList2Iterator is called in the first place: simply listing elements don't cause that.
          Hide
          Ilya Kasnacheev added a comment -

          The root problem seems to be caused because:
          kidOK[ELEMENT_NODE] =
          1 << ELEMENT_NODE | 1 << PROCESSING_INSTRUCTION_NODE |
          1 << COMMENT_NODE | 1 << TEXT_NODE |
          1 << CDATA_SECTION_NODE | 1 << ENTITY_REFERENCE_NODE ;

          So, ATTRIBUTE_NODE isn't okayish child for ELEMENT_NODE, thus, no cigar.

          I'm still contemplating that fact, to be fair.

          Show
          Ilya Kasnacheev added a comment - The root problem seems to be caused because: kidOK [ELEMENT_NODE] = 1 << ELEMENT_NODE | 1 << PROCESSING_INSTRUCTION_NODE | 1 << COMMENT_NODE | 1 << TEXT_NODE | 1 << CDATA_SECTION_NODE | 1 << ENTITY_REFERENCE_NODE ; So, ATTRIBUTE_NODE isn't okayish child for ELEMENT_NODE, thus, no cigar. I'm still contemplating that fact, to be fair.
          Hide
          Ilya Kasnacheev added a comment -

          See XALANJ-2425 also.

          Show
          Ilya Kasnacheev added a comment - See XALANJ-2425 also.
          Martin von Gagern made changes -
          Link This issue is part of XALANJ-2493 [ XALANJ-2493 ]
          Hide
          Henry Zongaro added a comment -

          Fixed under JIra XALANJ-2493.

          Show
          Henry Zongaro added a comment - Fixed under JIra XALANJ-2493 .
          Henry Zongaro made changes -
          Status Open [ 1 ] Resolved [ 5 ]
          Fix Version/s The Latest Development Code [ 12312206 ]
          Resolution Fixed [ 1 ]
          Mark Thomas made changes -
          Workflow jira [ 12422031 ] Default workflow, editable Closed status [ 12570991 ]
          Mark Thomas made changes -
          Workflow Default workflow, editable Closed status [ 12570991 ] jira [ 12594843 ]
          Gary Gregory made changes -
          Fix Version/s 2.7.2 [ 12323150 ]
          Transition Time In Source Status Execution Times Last Executer Last Execution Date
          Open Open Resolved Resolved
          670d 10h 26m 1 Henry Zongaro 25/Nov/09 21:56

            People

            • Assignee:
              Unassigned
              Reporter:
              Ilya Kasnacheev
            • Votes:
              1 Vote for this issue
              Watchers:
              1 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved:

                Development