stylesheet causes segfault in libxslt

Martin Gieseking <[email protected]> Mon, 23 Jul 2018 16:38:23 +0200
Newsgroups gmane.comp.gnome.lib.xslt
Message-ID <[email protected]>
Hello all,

I just stumbled over a segfault produced by one of my conversion scripts 
after updating from libxslt 1.1.28 to 1.1.32. The issue is caused by 
access of already freed heap memory in function xsltInitCtxtKey. After a 
bit of debugging and bisecting it turned out that the issue was probably 
introduced by
https://github.com/GNOME/libxslt/commit/470b17346163ba3deceb29eb4149ae140b595cdd.

Unfortunately, I wasn't able to create a trivial test case but reduced 
my stylesheet as much as possible to demonstrate the issue. Also, I 
don't yet have a patch to fix it, but maybe someone with a deeper 
understanding of the code details could help to isolate the bug.

When calling xsltproc with this XML file

<root>
   <A>
     <B/>
   </A>
</root>

and the stylesheet below, it segfaults. Here's the version of my 
xsltproc binary:

Using libxml 20908, libxslt 10132 and libexslt 820
xsltproc was compiled against libxml 20908, libxslt 10132 and libexslt 820
libxslt 10132 was compiled against libxml 20908
libexslt 820 was compiled against libxml 20908



<xsl:stylesheet version="1.0"
   xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
   xmlns:exsl="http://exslt.org/common"
   xmlns:func="http://exslt.org/functions"
   xmlns:mg="my-namespace"
   extension-element-prefixes="exsl func">

   <xsl:key name="dummy" match="A" use="mg:remove-space(B)"/>
   <xsl:key name="meta-by-self" match="meta" use="."/>

   <xsl:template match="/">
     <xsl:variable name="wrapper">
       <xsl:for-each select="//A">
         <wrapper>
           <meta/>
           <xsl:copy-of select="."/>
         </wrapper>
       </xsl:for-each>
     </xsl:variable>
     <xsl:for-each select="exsl:node-set($wrapper)/wrapper/meta">
       <xsl:value-of select="key('meta-by-self', .)"/>
     </xsl:for-each>
   </xsl:template>

   <func:function name="mg:remove-space">
     <xsl:param name="str"/>
     <func:result>
       <xsl:value-of select="mg:replace($str, ' ', '')"/>
     </func:result>
   </func:function>

   <func:function name="mg:replace">
     <xsl:param name="str"/>
     <xsl:param name="find"/>
     <xsl:param name="replace"/>
     <xsl:choose>
       <xsl:when test="contains($str, $find)">
         <xsl:variable name="pre" select="substring-before($str, $find)"/>
         <xsl:variable name="post" select="substring-after($str, $find)"/>
         <func:result select="concat($pre, $replace, mg:replace($post, 
$find, $replace))"/>
       </xsl:when>
       <xsl:otherwise>
         <func:result select="$str"/>
       </xsl:otherwise>
     </xsl:choose>
   </func:function>
</xsl:stylesheet>

When dropping the "dummy" key or replacing <func:result>...<func:result> 
with <func:result select...> in mg:remove-space, the issue goes away.

Any help would really be appreciated.

Best,
Martin