You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@xalan.apache.org by xa...@xml.apache.org on 2004/10/24 21:03:26 UTC

[jira] Resolved: (XALANC-425) The key() function can return wrong results on tree-fragments (memory management bug)

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: xalan-dev-unsubscribe@xml.apache.org
For additional commands, e-mail: xalan-dev-help@xml.apache.org