jkesselm    02/05/09 14:19:40

  Modified:    java/src/org/apache/xpath XPathContext.java
  Log:
  Fix for Bugzilla entries
        6833
        7023
        7123
        7410
  
  Basic summary of logic error: It is possible for multiple RTF DTMs
  to be pushed onto the stack between the start of a template and
  return from it. I hadn't anticipated that, so my pop logic was
  inadequate.
  
  I'm still not 110% sure I understand the case where this situation
  arises... I have a general intuition that it makes sense, but also a
  suspicion that there might be a way to avoid creating one of these
  DTMs. We should review that someday.
  
  Meanwhile, this fixes a whole batch of related bugs.
  
  Revision  Changes    Path
  1.38      +28 -8     xml-xalan/java/src/org/apache/xpath/XPathContext.java
  
  Index: XPathContext.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xpath/XPathContext.java,v
  retrieving revision 1.37
  retrieving revision 1.38
  diff -u -r1.37 -r1.38
  --- XPathContext.java 22 Mar 2002 00:53:08 -0000      1.37
  +++ XPathContext.java 9 May 2002 21:19:40 -0000       1.38
  @@ -110,6 +110,7 @@
   import org.apache.xml.utils.SAXSourceLocator;
   import org.apache.xml.utils.XMLString;
   import org.apache.xml.utils.XMLStringFactory;
  +import org.apache.xml.utils.IntStack;
   
   import org.apache.xpath.axes.DescendantIterator;
   
  @@ -124,6 +125,7 @@
    */
   public class XPathContext extends DTMManager // implements ExpressionContext
   {
  +     IntStack m_last_pushed_rtfdtm=new IntStack();   
     /**
      * Stack of cached "reusable" DTMs for Result Tree Fragments.
      * This is a kluge to handle the problem of starting an RTF before
  @@ -1270,6 +1272,10 @@
       m_rtfdtm_stack.addElement(rtfdtm);
                ++m_which_rtfdtm;
        }
  +     else if(m_which_rtfdtm<0)
  +     {
  +             rtfdtm=(SAX2RTFDTM)m_rtfdtm_stack.elementAt(++m_which_rtfdtm);
  +     }
        else
        {
                rtfdtm=(SAX2RTFDTM)m_rtfdtm_stack.elementAt(m_which_rtfdtm);
  @@ -1277,8 +1283,9 @@
                // It might already be under construction -- the classic example would 
be
                // an xsl:variable which uses xsl:call-template as part of its value. 
To
                // handle this recursion, we have to start a new RTF DTM, pushing the 
old
  -             // one onto a stack so we can return to it. It is hoped that
  -             // this is an uncommon case!
  +             // one onto a stack so we can return to it. This is not as uncommon a 
case
  +             // as we might wish, unfortunately, as some folks insist on coding XSLT
  +             // as if it were a procedural language...
                if(rtfdtm.isTreeIncomplete())
                {
                        if(++m_which_rtfdtm < m_rtfdtm_stack.size())
  @@ -1290,6 +1297,7 @@
                        }
                }
        }
  +             
       return rtfdtm;
     }
     
  @@ -1299,6 +1307,7 @@
      * */
     public void pushRTFContext()
     {
  +     m_last_pushed_rtfdtm.push(m_which_rtfdtm);
        if(null!=m_rtfdtm_stack)
                ((SAX2RTFDTM)(getRTFDTM())).pushRewindMark();
     }
  @@ -1321,11 +1330,22 @@
     {
        if(null==m_rtfdtm_stack)
                return;
  -             
  -     boolean 
isEmpty=((SAX2RTFDTM)(m_rtfdtm_stack.elementAt(m_which_rtfdtm))).popRewindMark();
  -     if(isEmpty && m_which_rtfdtm>0)
  -     {
  -             --m_which_rtfdtm;
  -     }
  +  
  +     int previous=m_last_pushed_rtfdtm.pop();
  +     if(m_which_rtfdtm==previous)
  +     {
  +             if(previous>=0) // guard against none-active
  +             {
  +                     boolean 
isEmpty=((SAX2RTFDTM)(m_rtfdtm_stack.elementAt(previous))).popRewindMark();
  +             }
  +     }
  +     else while(m_which_rtfdtm!=previous)
  +     {
  +             // Empty each DTM before popping, so it's ready for reuse
  +             // _DON'T_ pop the previous, since it's still open (which is why we
  +             // stacked up more of these) and did not receive a mark.
  +             boolean 
isEmpty=((SAX2RTFDTM)(m_rtfdtm_stack.elementAt(m_which_rtfdtm))).popRewindMark();
  +             --m_which_rtfdtm; 
  +     }
     }
   }
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to