#28807 [Opn->Csd]: Apache 2 child segfaults on request after script with xinclude

From: Date: Wed, 16 Jun 2004 22:45:58 +0000
Subject: #28807 [Opn->Csd]: Apache 2 child segfaults on request after script with xinclude
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-61006@lists.php.net to get a copy of this message
 ID:               28807
 User updated by:  rmolier at more-it dot com
 Reported By:      rmolier at more-it dot com
-Status:           Open
+Status:           Closed
 Bug Type:         DOM XML related
 Operating System: Fedora Core 1+2 / RHEL AS 3
 PHP Version:      4.3.6/4.3.2/4.3.4
 New Comment:

Finally (after two weeks of reinstalling, building etc.) I found a
simple workaround which works in my case.

1. XSLT->process($Doc,null,null,null,true); 

This is to create a copy of the XSLT document in order to replace the
nodes without problems. A case of RTFM. (or in this case, Find A Bug
That Seems Similar, and no there is no acronym for that yet... Any
suggestions?)

2. Replace the call-template in xslt by copy-of.

In XSLT processing I did not need to generate handmade copies of the
element, and now use <xsl:copy-of select="*"/>  in stead of the nice
call-template. This to stay away from some internal XSLT problems. This
problem wasn't solved by the first step though. A case of KISS, nothing
more nothing less. 

If this doesn't help for you, I guess you'll have to start crying
toward the developer of libxslt who most likely will be (partly)
responsible for the mess you are in.


Previous Comments:
------------------------------------------------------------------------

[2004-06-16 21:19:04] rmolier at more-it dot com

The segfault doesn't occur however...

------------------------------------------------------------------------

[2004-06-16 21:16:12] rmolier at more-it dot com

Even more funny:

It seems that only in the case the element was created in the
stylesheet function (which is basically a remove parent element from
list function) the memory leak occurs. Without the XMLInclude this
resulted in one extra free invalid pointer message().

I tested this by adding an additional element to the main document in
the following way:

/* code: begin */

$XMLIncludeElement = $XMLDom->create_element("include");
$XMLIncludedElement = $XMLDom->create_element("gettext");
$XMLIncludedElementText = $XMLDom->create_text_node("Text included in
main document");
$XMLIncludedElement->append_child($XMLIncludedElementText);
$XMLIncludeElement->append_child($XMLIncludedElement);
$XMLDocument->append_child($XMLIncludeElement);

/*code: end */

------------------------------------------------------------------------

[2004-06-16 20:48:26] rmolier at more-it dot com

With option 3 (DOM XML / XInclude /XSLT) I get after the third time:
Allowed memory size of 8388608 bytes exhausted (tried to allocate 10
bytes) and the process dies with 01.

------------------------------------------------------------------------

[2004-06-16 20:37:41] rmolier at more-it dot com

I found a way to reproduce the same behaviour in a simple script. I did
the following tests myself by commenting out some code:

1. DOM + XInclude + XSLT + Replacenode = problem
2. DOM + XInclude + Replacenode = no problem
3. DOM + XInclude + XSLT = no problem
4. DOM + XInclude = no problem
5. DOM + XSLT + Replacenode = no problem
6. DOM + Replacenode = no problem


For the people that would like to reproduce the bug I have created the
following script:

/* xmltest.php: begin */
<?php

echo "Starting Document<br>";

$XMLDom = domxml_new_doc("1.0");

$XMLDocument = $XMLDom->create_element("document");
$XMLDom->append_child($XMLDocument);

$XMLElement = $XMLDom->create_element("replace");
$XMLElementText = $XMLDom->create_text_node("replace this text");
$XMLElement->append_child($XMLElementText);
$XMLDocument->append_child($XMLElement);

$XMLInclude =
$XMLDom->create_element_ns("http://www.w3.org/2001/XInclude","include","xi");
$XMLInclude->set_attribute("href","include.xml");
$XMLDocument->append_child($XMLInclude);

echo "<pre>";
echo htmlentities($XMLDom->dump_mem(true));
echo "</pre>";

$XMLDom->xinclude();

echo "After Include<br>";
echo "<pre>";
echo htmlentities($XMLDom->dump_mem(true));
echo "</pre>";


$XSLTStylesheet = domxml_xslt_stylesheet_file("stylesheet.xslt");
$XSLTResult = $XSLTStylesheet->process($XMLDom);

echo "After Stylesheet<br>";
echo "<pre>";
echo htmlentities($XSLTResult->dump_mem(true));
echo "</pre>";



$XPathContext =  xpath_new_context($XSLTResult);

$XPathResult = xpath_eval($XPathContext,"//gettext");

echo "<pre>";
print_r($XPathResult);
echo "</pre>";

foreach ($XPathResult->nodeset as $XPathNode)
{
    $XMLParentNode = $XPathNode->parent_node();
    $XMLElementText = $XPathNode->first_child();
    $Text = $XMLElementText->get_content();
    $XMLTextNode = $XSLTResult->create_text_node($Text);
    $XPathNode->replace_node($XMLTextNode);
}

echo "After Replace<br>";
echo "<pre>";
echo htmlentities($XSLTResult->dump_mem(true));
echo "</pre>";
?>

/* xmltest: end */

/* include.xml: begin */

<?xml version="1.0" encoding="UTF-8" ?>
<include>
	<gettext>This is the included replace</gettext>
</include>

/* include.xml: end */

/* stylesheet.xslt */ 

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
	<xsl:output method="xml" version="1.0" encoding="UTF-8"
indent="yes"/>
	
	<xsl:template match="/">
		<document>
			<xsl:apply-templates/>
		</document>
	</xsl:template>
	
	<xsl:template match="replace">
		<gettext>
			<xsl:value-of select="."/>
		</gettext>
	</xsl:template>
	
	
	<xsl:template name="display-element">
		<xsl:element name="{name()}">
			<xsl:for-each select="@*">
				<xsl:attribute name="{name()}">
					<xsl:value-of select="."/>
				</xsl:attribute>
			</xsl:for-each>
			<xsl:choose>
				<xsl:when test="count(*) !=0">
					<xsl:for-each select="*">
						<xsl:call-template name="display-element"/>
					</xsl:for-each>
				</xsl:when>
				<xsl:otherwise>
					<xsl:value-of select="."/>
				</xsl:otherwise>
			</xsl:choose>
			
			
		</xsl:element>	
	</xsl:template>
		
	
	<xsl:template match="include">
		<xsl:for-each select="*">
			<xsl:call-template name="display-element"/>
		</xsl:for-each>
	</xsl:template>
</xsl:stylesheet>

/* stylesheet.xslt */

------------------------------------------------------------------------

[2004-06-16 19:06:58] rmolier at more-it dot com

To clarify a little on the magical number of 17. It seems, that after
performing the xinclude I perform exactly 17 node replaces on the
included nodes.. 

Think that the problem can be found somewhere there.....

Flow for reproducing:

Create a document from scratch.
Add a number of xinclude statements.
Perform an Xinclude
Perform an XSLT transformation.
Perform an Xpath query on the document.
Replace the resulting nodes with text nodes.

------------------------------------------------------------------------

The remainder of the comments for this report are too long. To view
the rest of the comments, please view the bug report online at
    http://bugs.php.net/28807

-- 
Edit this bug report at http://bugs.php.net/?id=28807&edit=1


Thread (7 messages)

« previous php.bugs (#61006) next »