[libxslt] Backup context node in exsltFuncFunctionFunction



commit 45d1d8597ed1b330ff059dcde81a8d09c477a049
Author: Nick Wellnhofer <wellnhofer aevum de>
Date:   Tue Feb 12 01:52:31 2019 +0100

    Backup context node in exsltFuncFunctionFunction
    
    exsltFuncFunctionFunction handles XPath extension functions and is called
    from the XPath engine. Since evaluation of function templates can change
    the XPath context node, it must be backed up to avoid corruption.
    
    Without proper backup, evaluating certain content in function templates
    could also result in use-after-free errors.
    
    It seems that libxml2 commit 029d0e96 helped to expose the error.
    
    Fixes #11.

 libexslt/functions.c      |  6 +++++-
 tests/docs/bug-216.xml    |  1 +
 tests/general/bug-216.out |  2 ++
 tests/general/bug-216.xsl | 11 +++++++++++
 4 files changed, 19 insertions(+), 1 deletion(-)
---
diff --git a/libexslt/functions.c b/libexslt/functions.c
index 075e2366..41d37493 100644
--- a/libexslt/functions.c
+++ b/libexslt/functions.c
@@ -291,7 +291,7 @@ exsltFuncFunctionFunction (xmlXPathParserContextPtr ctxt, int nargs) {
     xmlXPathObjectPtr oldResult, ret;
     exsltFuncData *data;
     exsltFuncFunctionData *func;
-    xmlNodePtr paramNode, oldInsert, fake;
+    xmlNodePtr paramNode, oldInsert, oldXPNode, fake;
     int oldBase;
     void *oldCtxtVar;
     xsltStackElemPtr params = NULL, param;
@@ -360,6 +360,9 @@ exsltFuncFunctionFunction (xmlXPathParserContextPtr ctxt, int nargs) {
     }
     tctxt->depth++;
 
+    /* Evaluating templates can change the XPath context node. */
+    oldXPNode = tctxt->xpathCtxt->node;
+
     /*
      * We have a problem with the evaluation of function parameters.
      * The original library code did not evaluate XPath expressions until
@@ -446,6 +449,7 @@ exsltFuncFunctionFunction (xmlXPathParserContextPtr ctxt, int nargs) {
     data->ctxtVar = oldCtxtVar;
     if (params != NULL)
        xsltFreeStackElemList(params);
+    tctxt->xpathCtxt->node = oldXPNode;
 
     if (data->error != 0)
         goto error;
diff --git a/tests/docs/bug-216.xml b/tests/docs/bug-216.xml
new file mode 100644
index 00000000..d128aecc
--- /dev/null
+++ b/tests/docs/bug-216.xml
@@ -0,0 +1 @@
+<top xmlns:ns1="abc"/>
diff --git a/tests/general/bug-216.out b/tests/general/bug-216.out
new file mode 100644
index 00000000..40f6b10c
--- /dev/null
+++ b/tests/general/bug-216.out
@@ -0,0 +1,2 @@
+<?xml version="1.0"?>
+10
diff --git a/tests/general/bug-216.xsl b/tests/general/bug-216.xsl
new file mode 100644
index 00000000..50cc4b11
--- /dev/null
+++ b/tests/general/bug-216.xsl
@@ -0,0 +1,11 @@
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"; xmlns:func="http://exslt.org/functions"; 
version="1.0" extension-element-prefixes="func">
+  <func:function name="func:f">
+    <xsl:for-each select="namespace::*">
+      <xsl:sort/>
+    </xsl:for-each>
+    <func:result>10</func:result>
+  </func:function>
+  <xsl:template match="*">
+    <xsl:value-of select="func:f()+count(abc)"/>
+  </xsl:template>
+</xsl:stylesheet>


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]