summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristoph M. Becker <cmbecker69@gmx.de>2020-01-30 13:05:49 +0100
committerChristoph M. Becker <cmbecker69@gmx.de>2020-01-30 13:06:25 +0100
commitdfbeee034a24fe01166e69369c0df2d7921817f8 (patch)
tree6ca8a3e919a0238c8443e0b4a7230828ae8e36cf
parent187f359549dcd7b172806d79b40807a284b5fdad (diff)
parent8226e704e4e6066a5bd41b57b2934a3371896be2 (diff)
downloadphp-git-dfbeee034a24fe01166e69369c0df2d7921817f8.tar.gz
Merge branch 'PHP-7.3' into PHP-7.4
* PHP-7.3: Fix #70078: XSL callbacks with nodes as parameter leak memory
-rw-r--r--NEWS3
-rw-r--r--ext/xsl/tests/bug70078.phpt51
-rw-r--r--ext/xsl/xsltprocessor.c2
3 files changed, 55 insertions, 1 deletions
diff --git a/NEWS b/NEWS
index 13bcaebde3..2dcfdf9db3 100644
--- a/NEWS
+++ b/NEWS
@@ -54,6 +54,9 @@ PHP NEWS
. Fixed bug #78902 (Memory leak when using stream_filter_append). (liudaixiao)
. Fixed bug #78969 (PASSWORD_DEFAULT should match PASSWORD_BCRYPT instead of being null). (kocsismate)
+- XSL:
+ . Fixed bug #70078 (XSL callbacks with nodes as parameter leak memory). (cmb)
+
- Zip:
. Add ZipArchive::CM_LZMA2 and ZipArchive::CM_XZ constants (since libzip 1.6.0). (remi)
. Add ZipArchive::ER_* missing constants. (remi)
diff --git a/ext/xsl/tests/bug70078.phpt b/ext/xsl/tests/bug70078.phpt
new file mode 100644
index 0000000000..41e9485a0f
--- /dev/null
+++ b/ext/xsl/tests/bug70078.phpt
@@ -0,0 +1,51 @@
+--TEST--
+Bug #70078 (XSL callbacks with nodes as parameter leak memory)
+--SKIPIF--
+<?php
+if (!extension_loaded('xsl')) die('skip xsl extension not available');
+?>
+--FILE--
+<?php
+// create big dummy document:
+$dom = new \DOMDocument();
+$rootNode = $dom->appendChild($dom->createElement('root'));
+for ($i = 0; $i <= 100; $i++) {
+ $level1Node = $rootNode->appendChild($dom->createElement('level1'));
+ for ($j = 0; $j <= 100; $j++) {
+ $level2Node = $level1Node->appendChild($dom->createElement('level2'));
+ for ($k = 0; $k <= 10; $k++) {
+ $level3Node = $level2Node->appendChild($dom->createElement('level3', 'test'));
+ }
+ }
+}
+
+function testPhpFunction($node) {
+ return 'test2';
+}
+
+$xslStr = <<<EOF
+<?xml version="1.0" encoding="utf-8"?>
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:php="http://php.net/xsl">
+ <xsl:template match="root">
+ <output>
+ <xsl:for-each select="level1">
+ <node>
+ <xsl:value-of select="php:function('testPhpFunction', .)" />
+ </node>
+ </xsl:for-each>
+ </output>
+ </xsl:template>
+</xsl:stylesheet>
+EOF;
+
+$xsl = new \DOMDocument();
+$xsl->loadXML($xslStr);
+$xslt = new \XSLTProcessor();
+$xslt->registerPHPFunctions('testPhpFunction');
+$xslt->importStyleSheet($xsl);
+
+echo $xslt->transformToXML($dom);
+?>
+--EXPECT--
+<?xml version="1.0"?>
+<output xmlns:php="http://php.net/xsl"><node>test2</node><node>test2</node><node>test2</node><node>test2</node><node>test2</node><node>test2</node><node>test2</node><node>test2</node><node>test2</node><node>test2</node><node>test2</node><node>test2</node><node>test2</node><node>test2</node><node>test2</node><node>test2</node><node>test2</node><node>test2</node><node>test2</node><node>test2</node><node>test2</node><node>test2</node><node>test2</node><node>test2</node><node>test2</node><node>test2</node><node>test2</node><node>test2</node><node>test2</node><node>test2</node><node>test2</node><node>test2</node><node>test2</node><node>test2</node><node>test2</node><node>test2</node><node>test2</node><node>test2</node><node>test2</node><node>test2</node><node>test2</node><node>test2</node><node>test2</node><node>test2</node><node>test2</node><node>test2</node><node>test2</node><node>test2</node><node>test2</node><node>test2</node><node>test2</node><node>test2</node><node>test2</node><node>test2</node><node>test2</node><node>test2</node><node>test2</node><node>test2</node><node>test2</node><node>test2</node><node>test2</node><node>test2</node><node>test2</node><node>test2</node><node>test2</node><node>test2</node><node>test2</node><node>test2</node><node>test2</node><node>test2</node><node>test2</node><node>test2</node><node>test2</node><node>test2</node><node>test2</node><node>test2</node><node>test2</node><node>test2</node><node>test2</node><node>test2</node><node>test2</node><node>test2</node><node>test2</node><node>test2</node><node>test2</node><node>test2</node><node>test2</node><node>test2</node><node>test2</node><node>test2</node><node>test2</node><node>test2</node><node>test2</node><node>test2</node><node>test2</node><node>test2</node><node>test2</node><node>test2</node><node>test2</node><node>test2</node><node>test2</node></output>
diff --git a/ext/xsl/xsltprocessor.c b/ext/xsl/xsltprocessor.c
index 20d907dc4a..079920d0ff 100644
--- a/ext/xsl/xsltprocessor.c
+++ b/ext/xsl/xsltprocessor.c
@@ -277,7 +277,7 @@ static void xsl_ext_function_php(xmlXPathParserContextPtr ctxt, int nargs, int t
node->parent = nsparent;
node->ns = curns;
} else {
- node = xmlDocCopyNodeList(domintern->document->ptr, node);
+ node = xmlDocCopyNode(node, domintern->document->ptr, 1);
}
php_dom_create_object(node, &child, domintern);