Skip to content

Commit 2dc5077

Browse files
committed
Merge branch 'PHP-7.4'
* PHP-7.4: Fix #70078: XSL callbacks with nodes as parameter leak memory
2 parents 0078727 + dfbeee0 commit 2dc5077

File tree

2 files changed

+52
-1
lines changed

2 files changed

+52
-1
lines changed

ext/xsl/tests/bug70078.phpt

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
--TEST--
2+
Bug #70078 (XSL callbacks with nodes as parameter leak memory)
3+
--SKIPIF--
4+
<?php
5+
if (!extension_loaded('xsl')) die('skip xsl extension not available');
6+
?>
7+
--FILE--
8+
<?php
9+
// create big dummy document:
10+
$dom = new \DOMDocument();
11+
$rootNode = $dom->appendChild($dom->createElement('root'));
12+
for ($i = 0; $i <= 100; $i++) {
13+
$level1Node = $rootNode->appendChild($dom->createElement('level1'));
14+
for ($j = 0; $j <= 100; $j++) {
15+
$level2Node = $level1Node->appendChild($dom->createElement('level2'));
16+
for ($k = 0; $k <= 10; $k++) {
17+
$level3Node = $level2Node->appendChild($dom->createElement('level3', 'test'));
18+
}
19+
}
20+
}
21+
22+
function testPhpFunction($node) {
23+
return 'test2';
24+
}
25+
26+
$xslStr = <<<EOF
27+
<?xml version="1.0" encoding="utf-8"?>
28+
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:php="http://php.net/xsl">
29+
<xsl:template match="root">
30+
<output>
31+
<xsl:for-each select="level1">
32+
<node>
33+
<xsl:value-of select="php:function('testPhpFunction', .)" />
34+
</node>
35+
</xsl:for-each>
36+
</output>
37+
</xsl:template>
38+
</xsl:stylesheet>
39+
EOF;
40+
41+
$xsl = new \DOMDocument();
42+
$xsl->loadXML($xslStr);
43+
$xslt = new \XSLTProcessor();
44+
$xslt->registerPHPFunctions('testPhpFunction');
45+
$xslt->importStyleSheet($xsl);
46+
47+
echo $xslt->transformToXML($dom);
48+
?>
49+
--EXPECT--
50+
<?xml version="1.0"?>
51+
<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>

ext/xsl/xsltprocessor.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -275,7 +275,7 @@ static void xsl_ext_function_php(xmlXPathParserContextPtr ctxt, int nargs, int t
275275
node->parent = nsparent;
276276
node->ns = curns;
277277
} else {
278-
node = xmlDocCopyNodeList(domintern->document->ptr, node);
278+
node = xmlDocCopyNode(node, domintern->document->ptr, 1);
279279
}
280280

281281
php_dom_create_object(node, &child, domintern);

0 commit comments

Comments
 (0)