<?php
// external.xml: <root xmlns:custom="urn:custom"><data>secret</data></root>
$stored_ns = null;
function capture_ns($nodes) {
global $stored_ns;
// $nodes contains DOMNameSpaceNode from external document
if (is_array($nodes)) {
foreach ($nodes as $node) {
if ($node instanceof DOMNameSpaceNode) {
$stored_ns = $node; // retain reference
}
}
}
return "captured";
}
$xsl = new DOMDocument();
$xsl->loadXML('<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:php="http://php.net/xsl">
<xsl:template match="/">
<result>
<xsl:value-of select="php:function(
\'capture_ns\',
document(\'external.xml\')/*/namespace::*
)"/>
</result>
</xsl:template>
</xsl:stylesheet>');
$doc = new DOMDocument();
$doc->loadXML('<input/>');
$proc = new XSLTProcessor();
$proc->registerPHPFunctions();
$proc->importStylesheet($xsl);
$result = $proc->transformToXml($doc);
// xsltFreeTransformContext() has now freed the external document
// All three accesses dereference freed memory:
var_dump($stored_ns->parentNode); // freed 120B element node
var_dump($stored_ns->localName); // freed 1048B dict string storage
var_dump($stored_ns->ownerDocument); // freed 176B xmlDoc structure
Description
Originally reported by @ExPatch-LLC.
PHP Version
Operating System
No response