reassign 568382 libxml-libxslt-perl
thanks

I'm now becoming convinced that this is a memory management issue
between Perl and libxslt - I think that both are trying to free the
same objects.  So I'm reassigning this - feel free to punt it back to
libxslt if appropriate.

The following code should demonstrate this, and gives a good backtrace
under GDB (try it with and without the 'push @keep'):

#!/usr/bin/perl -w

use strict;
use warnings;

use XML::LibXSLT;
use XML::LibXML;

my $xslt = XML::LibXSLT->new();
my $ext_uri = "urn:local";
my @keep;
XML::LibXSLT->register_function($ext_uri, "uc", sub { push @keep, @_; return uc shift; } );

my $stylesheet = $xslt->parse_stylesheet(XML::LibXML->load_xml(string => <<'EOF'));
<xsl:stylesheet version="1.0"
                extension-element-prefixes="exsl local"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
                xmlns:exsl="http://exslt.org/common"; 
                xmlns:local="urn:local">
  <xsl:template match="/">
    <xsl:variable name="foo"><foo a="foo"/></xsl:variable>
    <bar><xsl:value-of select="local:uc(exsl:node-set($foo)//@a)"/></bar>
  </xsl:template>
</xsl:stylesheet>
EOF

my $input = XML::LibXML->load_xml(string => "<input/>");
print $stylesheet->transform($input)->toString;

# Next line crashes Perl
@keep = undef;
Further experimentation shows that this issue is not triggered if I
select the text content instead of the attribute to pass to the
extension function - this may be a basis for a workaround for me.
Alternatively, going through a second variable seems to work, thus:

#!/usr/bin/perl -w

use strict;
use warnings;

use XML::LibXSLT;
use XML::LibXML;

my $xslt = XML::LibXSLT->new();
my $ext_uri = "urn:local";

XML::LibXSLT->register_function($ext_uri, "uc", sub { return uc shift; } );

my $stylesheet = $xslt->parse_stylesheet(XML::LibXML->load_xml(string => <<'EOF'));
<xsl:stylesheet version="1.0"
                extension-element-prefixes="exsl local"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
                xmlns:exsl="http://exslt.org/common"; 
                xmlns:local="urn:local">
  <xsl:template match="/">
    <xsl:variable name="foo"><foo a="foo"/></xsl:variable>
    <xsl:variable name="bar"><xsl:value-of select="exsl:node-set($foo)//@a"/></xsl:variable>
    <bar><xsl:value-of select="local:uc($bar)"/></bar>
  </xsl:template>
</xsl:stylesheet>
EOF

my $input = XML::LibXML->load_xml(string => "<input/>");
print $stylesheet->transform($input)->toString;

Reply via email to