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;