After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 328218 - Already freed chunk warning from accessing union'd node-set('text')s
Already freed chunk warning from accessing union'd node-set('text')s
Status: RESOLVED FIXED
Product: libxslt
Classification: Platform
Component: general
1.1.15
Other All
: Normal normal
: ---
Assigned To: kbuchcik
libxml QA maintainers
Depends on:
Blocks:
 
 
Reported: 2006-01-22 21:51 UTC by James William Pye
Modified: 2006-07-14 16:21 UTC
See Also:
GNOME target: ---
GNOME version: 2.11/2.12



Description James William Pye 2006-01-22 21:51:28 UTC
Please describe the problem:
A warning is thrown about an already free chunk. I imagine this is pointing at a
bug somewhere. See "How To Reproduce", to, uh, reproduce it. =)

(I wasn't sure what I'd get from this xslt code, and thus my testing.)

Steps to reproduce:
<?xml version="1.0" encoding="utf-8"?>
<transform version="1.0"
 xmlns="http://www.w3.org/1999/XSL/Transform"
 xmlns:xl="http://www.w3.org/1999/xlink"
 xmlns:set="http://exslt.org/sets"
 xmlns:exsl="http://exslt.org/common"
 xmlns:func="http://exslt.org/functions"
 xmlns:ds="http://jwp.name/xml/ds"
 extension-element-prefixes="func"
>
 <template match="/">
  <variable name="foo" select="exsl:node-set('foo')|exsl:node-set('bar')"/>
  <message><value-of select="$foo/text()[position()=first()]"/></message>
  <message><value-of select="$foo/text()[position()=last()]"/></message>
 </template>
</transform>

Actual results:
It gives a warning about an already free chunk of memory:

xsltproc in free(): warning: chunk is already free
xsltproc in free(): warning: chunk is already free


Expected results:
Not get warnings.

Does this happen every time?
Yes.

Other information:
$ xsltproc --version

Using libxml 20622, libxslt 10115 and libexslt 812
xsltproc was compiled against libxml 20622, libxslt 10115 and libexslt 812
libxslt 10115 was compiled against libxml 20622
libexslt 812 was compiled against libxml 20622


$ uname -a

FreeBSD lit 6.0-STABLE FreeBSD 6.0-STABLE #1: Sat Dec 31 23:42:00 MST 2005    
root@lit:/usr/obj/usr/src/sys/void  i386


This xsltproc comes from FreeBSD's precompiled libxslt package(built from their
port system).
Comment 1 kbuchcik 2006-07-14 11:57:26 UTC
This is a bug. In exsltNodeSetFunction() (libexslt/common.c)
a tree fragment is created with xmlXPathNewValueTree(), containing
a single text node (without a doc). There are two errors here:
1) there's no tree fragment (an xmlDoc in Libxml2)
2) the @boolval of the XPath object is not reset to 0; this means that
   the XPath module will free the text node, when the XPath object
   is freed.

Due to 2), and the fact that the two text nodes "foo" and "bar" are
unioned with xmlXPathNodeSetMerge(), creates a scenario where
a text node is exitent in two node sets: the first is an XSLT tree fragment,
the second a normal node set. Somewhere in the machinery the XPath
object, which reflects the tree fragment is freed and with it the text
node. The node set, which was the result of the node set merge, is
still accessible and contains a reference to this already freed text node.

How to fix:
1) Create a tree fragment for the text nodes with xsltCreateRVT() and
   register it locally with xsltRegisterLocalRVT().
   Add the text node to the fragment.
2) Use xmlXPathNewNodeSet() to store the text node in a node set; this
   will prevent it from being freed by the XPath module.

I applied this fix to my local code and it works fine, except for the
fact that it still crashes, since my new tree fragment garbage
collecting mechanism will free the tree fragments too early.
So in the case of tree fragments created during the evaluation of
and xsl:variable and xsl:param we need to bing the fragments to the
scope of the xsl:variable or xsl:param.
   
Comment 2 kbuchcik 2006-07-14 11:59:51 UTC
The corrected test case:

<?xml version="1.0"?>
<transform version="1.0" xmlns="http://www.w3.org/1999/XSL/Transform"
  xmlns:exsl="http://exslt.org/common">

  <template match="/">
    <variable name="foo" select="exsl:node-set('foo') | exsl:node-set('bar')"/>
    <copy-of select="$foo[position() = 1]"/>
    <copy-of select="$foo[position() = 2]"/>
  </template>

</transform>
Comment 3 kbuchcik 2006-07-14 16:21:05 UTC
Fixed in CVS.

Thanks for the report!