Message:

   The following issue has been resolved as FIXED.

   Resolver: David Bertoni
       Date: Sun, 24 Oct 2004 12:02 PM

A fix is in CVS.  Can you please verify, if possible?  Thanks!
---------------------------------------------------------------------
View the issue:
  http://issues.apache.org/jira/browse/XALANC-425

Here is an overview of the issue:
---------------------------------------------------------------------
        Key: XALANC-425
    Summary: The key() function can return wrong results on tree-fragments (memory 
management bug)
       Type: Bug

     Status: Resolved
 Resolution: FIXED

    Project: XalanC
 Components: 
             XalanC
   Fix Fors:
             CurrentCVS
   Versions:
             1.8

   Assignee: 
   Reporter: Alain Le Guennec

    Created: Wed, 30 Jun 2004 8:22 AM
    Updated: Sun, 24 Oct 2004 12:02 PM
Environment: Operating System: Windows NT/2K
Platform: PC

Description:
I think there is a bug in key maps management in XalanC 1.8.0.
A new map is created when the key() function is used on a tree-fragment
to store key-value/node-list pairs for that key within that tree-fragment.
However, this new map is not deleted when the tree-fragment goes out of scope.
Moreover, the tree-fragment allocator might reuse the address of a previous
tree-fragment for a new one.
This results in the previous map(s) being reused for the new tree-fragment too,
instead of rebuilding new, up-to-date, map(s).
Below is a small test case (which does not depend on the actual input file),
and a proposed fix to be applied to function returnXResultTreeFrag() in
StylesheetExecutionContextDefault.cpp (which adds clean-up of the map entries
for the tree-fragment going out of scope).
Best regards,
Alain Le Guennec.
- -----------------------
- The test case:
- -----------------------
<?xml version="1.0"  encoding = "ISO-8859-1"?>
<xsl:stylesheet version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
                xmlns:exsl="http://exslt.org/common";
                xmlns:math="http://exslt.org/math";
                xmlns:dyn="http://exslt.org/dynamic";
                xmlns:set="http://exslt.org/sets";
                xmlns:xalan="http://xml.apache.org/xalan";
                exclude-result-prefixes="exsl">

<xsl:key name="node-name" match="NODE" use="@name"/>

<xsl:template match="/">
        <xsl:call-template name="bug"><xsl:with-param name="para"
select="'foo'"/></xsl:call-template>
        <xsl:call-template name="bug"><xsl:with-param name="para"
select="'bar'"/></xsl:call-template>
</xsl:template>

<xsl:template name="bug">
        <xsl:param name="para"/>
        <xsl:variable name="fragment">
                <NODE name="{$para}"/>
        </xsl:variable>
        <xsl:for-each select="exsl:node-set($fragment)/*">
                <xsl:for-each select=".">
                        <xsl:variable name="homonymous" select="key('node-name', 
@name)"/>
                        <xsl:if test="count($homonymous) = 0">
                                <xsl:message>Bug in key(): No NODE with 
name=<xsl:value-of select="@name"/>
found!</xsl:message>
                        </xsl:if>
                </xsl:for-each>
        </xsl:for-each>
</xsl:template>

</xsl:stylesheet>
- -----------------------
And now the proposed fix:
- -----------------------
bool
StylesheetExecutionContextDefault::returnXResultTreeFrag(XResultTreeFrag*
theXResultTreeFrag)
{
        assert(theXResultTreeFrag != 0);

        KeyTablesTableType::iterator i = 
m_keyTables.find(&theXResultTreeFrag->rtree());
        if (i != m_keyTables.end())
        {
                delete (*i).second;
                m_keyTables.erase(i);
        }

        if (m_xresultTreeFragAllocator.ownsObject(theXResultTreeFrag) == false)
        {
                return false;
        }
        else
        {
                XalanDocumentFragment* const    theDocumentFragment =
                        theXResultTreeFrag->release();

                m_xresultTreeFragAllocator.destroy(theXResultTreeFrag);

                if (m_usePerInstanceDocumentFactory == true)
                {
#if defined(XALAN_OLD_STYLE_CASTS)
                
m_documentAllocator.destroy((XalanSourceTreeDocument*)theDocumentFragment->getOwnerDocument());
#else
                
m_documentAllocator.destroy(static_cast<XalanSourceTreeDocument*>(theDocumentFragment->getOwnerDocument()));
#endif
                }

#if defined(XALAN_OLD_STYLE_CASTS)
        
m_documentFragmentAllocator.destroy((XalanSourceTreeDocumentFragment*)theDocumentFragment);
#else
        
m_documentFragmentAllocator.destroy(static_cast<XalanSourceTreeDocumentFragment*>(theDocumentFragment));
#endif

        return true;
        }
}


---------------------------------------------------------------------
JIRA INFORMATION:
This message is automatically generated by JIRA.

If you think it was sent incorrectly contact one of the administrators:
   http://issues.apache.org/jira/secure/Administrators.jspa

If you want more information on JIRA, or have a bug to report see:
   http://www.atlassian.com/software/jira


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

Reply via email to