php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #49634 Segfault throwing an exception in a XSL registered function
Submitted: 2009-09-22 22:41 UTC Modified: 2013-12-02 11:29 UTC
Votes:4
Avg. Score:4.0 ± 1.0
Reproduced:2 of 3 (66.7%)
Same Version:1 (50.0%)
Same OS:0 (0.0%)
From: aldo at armiento dot com Assigned: mike (profile)
Status: Closed Package: XSLT related
PHP Version: 5.* OS: Linux Debian, Mac OSX
Private report: No CVE-ID: None
 [2009-09-22 22:41 UTC] aldo at armiento dot com
Description:
------------
Segfault throwing an exception in an XSL registered function when try to 
access node from an external document.

libxml2: 2.7.4
libxslt: 1.1.25

Reproduce code:
---------------
External document doc.xml:

<root/>

Script:

<?php

$sXml = <<<XML
<?xml version="1.0" encoding="UTF-8" ?>
<root>
	test
</root>
XML;

$sXsl = <<<XSL
<xsl:stylesheet version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:ext="http://php.net/xsl"
                xsl:extension-element-prefixes="ext"
                exclude-result-prefixes="ext">
	<xsl:output encoding="UTF-8" indent="yes" method="xml" />
	<xsl:template match="/">
		<xsl:value-of select="ext:function('testFunction', document('doc.xml')/root)"/>
	</xsl:template>
</xsl:stylesheet>
XSL;

function testFunction($a)
{
	throw new Exception('Test exception.');
}

$domXml = DOMDocument::loadXML($sXml);
$domXsl = DOMDocument::loadXML($sXsl);

for ($i = 0; $i < 10; $i++)
{
	$xsltProcessor = new XSLTProcessor();
	$xsltProcessor->registerPHPFunctions(array('testFunction'));
	$xsltProcessor->importStyleSheet($domXsl);
	try {
		@$xsltProcessor->transformToDoc($domXml);
	} catch (Exception $e) {
		echo "Exception!\n";
	}
}

Expected result:
----------------
Exception!
Exception!
Exception!
Exception!
Exception!
Exception!
Exception!
Exception!
Exception!
Exception!

Actual result:
--------------
(gdb) r
Starting program: /home/armiento/env/spider/bin/php test_segfault.php
[Thread debugging using libthread_db enabled]
[New Thread 140442269927120 (LWP 3340)]
Exception!
Exception!
*** glibc detected *** free(): invalid pointer: 0x000000000137d0d0 ***

Program received signal SIGABRT, Aborted.
[Switching to Thread 140442269927120 (LWP 3340)]
0x00007fbb423cb07b in raise () from /lib/libc.so.6
(gdb) bt
#0  0x00007fbb423cb07b in raise () from /lib/libc.so.6
#1  0x00007fbb423cc84e in abort () from /lib/libc.so.6
#2  0x00007fbb424015f9 in __fsetlocking () from /lib/libc.so.6
#3  0x00007fbb42408163 in mallopt () from /lib/libc.so.6
#4  0x00007fbb424081ee in free () from /lib/libc.so.6
#5  0x000000000044f3ab in php_libxml_node_decrement_resource 
(object=0x7fbb439a0710)
    at /home/armiento/src/php-5.3.0/ext/libxml/libxml.c:1058
#6  0x00000000004caed5 in dom_objects_free_storage 
(object=0x7fbb439a0710) at /home/armiento/src/php-
5.3.0/ext/dom/php_dom.c:1017
#7  0x00000000006bf026 in zend_objects_store_del_ref_by_handle_ex 
(handle=3, handlers=<value optimized out>)
    at /home/armiento/src/php-5.3.0/Zend/zend_objects_API.c:220
#8  0x00000000006bf062 in zend_objects_store_del_ref 
(zobject=0x7fbb4399e4f0)
    at /home/armiento/src/php-5.3.0/Zend/zend_objects_API.c:172
#9  0x0000000000692cc5 in _zval_ptr_dtor (zval_ptr=0x7fbb439a0e40) at 
/home/armiento/src/php-5.3.0/Zend/zend_variables.h:35
#10 0x00000000006aab88 in zend_hash_destroy (ht=0x7fbb439a0d80) at 
/home/armiento/src/php-5.3.0/Zend/zend_hash.c:526
#11 0x000000000069ec36 in _zval_dtor_func (zvalue=0x7fbb439a0d50) at 
/home/armiento/src/php-5.3.0/Zend/zend_variables.c:43
#12 0x0000000000692cc5 in _zval_ptr_dtor (zval_ptr=0x7fbb439a0e98) at 
/home/armiento/src/php-5.3.0/Zend/zend_variables.h:35
#13 0x00000000006aab88 in zend_hash_destroy (ht=0x7fbb439a0ca8) at 
/home/armiento/src/php-5.3.0/Zend/zend_hash.c:526
#14 0x000000000069ec36 in _zval_dtor_func (zvalue=0x7fbb439a0c78) at 
/home/armiento/src/php-5.3.0/Zend/zend_variables.c:43
#15 0x0000000000692cc5 in _zval_ptr_dtor (zval_ptr=0x7fbb439a0ef0) at 
/home/armiento/src/php-5.3.0/Zend/zend_variables.h:35
#16 0x00000000006aab88 in zend_hash_destroy (ht=0x7fbb439a0ba0) at 
/home/armiento/src/php-5.3.0/Zend/zend_hash.c:526
#17 0x000000000069ec36 in _zval_dtor_func (zvalue=0x7fbb439a0b70) at 
/home/armiento/src/php-5.3.0/Zend/zend_variables.c:43
#18 0x0000000000692cc5 in _zval_ptr_dtor (zval_ptr=0x7fbb439a0f50) at 
/home/armiento/src/php-5.3.0/Zend/zend_variables.h:35
#19 0x00000000006aab88 in zend_hash_destroy (ht=0x7fbb439a0ac8) at 
/home/armiento/src/php-5.3.0/Zend/zend_hash.c:526
#20 0x000000000069ec36 in _zval_dtor_func (zvalue=0x7fbb439a00f0) at 
/home/armiento/src/php-5.3.0/Zend/zend_variables.c:43
#21 0x0000000000692cc5 in _zval_ptr_dtor (zval_ptr=0x7fbb439a0a08) at 
/home/armiento/src/php-5.3.0/Zend/zend_variables.h:35
#22 0x00000000006aab88 in zend_hash_destroy (ht=0x7fbb439a0930) at 
/home/armiento/src/php-5.3.0/Zend/zend_hash.c:526
#23 0x00000000006bb989 in zend_object_std_dtor (object=0x7fbb439a0780) 
at /home/armiento/src/php-5.3.0/Zend/zend_objects.c:45
#24 0x00000000006bb9a9 in zend_objects_free_object_storage 
(object=0xd0c) at /home/armiento/src/php-5.3.0/Zend/zend_objects.c:114
#25 0x00000000006bf026 in zend_objects_store_del_ref_by_handle_ex 
(handle=7, handlers=<value optimized out>)
    at /home/armiento/src/php-5.3.0/Zend/zend_objects_API.c:220
#26 0x00000000006bf062 in zend_objects_store_del_ref 
(zobject=0x7fbb439a1680)
    at /home/armiento/src/php-5.3.0/Zend/zend_objects_API.c:172
#27 0x0000000000692cc5 in _zval_ptr_dtor (zval_ptr=0x7fbb439a01b8) at 
/home/armiento/src/php-5.3.0/Zend/zend_variables.h:35
#28 0x00000000006ac7f7 in _zend_hash_quick_add_or_update (ht=0xcfa568, 
arKey=0x7fbb4399e360 "e", nKeyLength=2, h=5863242, 
    pData=0xcfa7b0, nDataSize=8, pDest=0x7fbb417b7118, flag=1) at 
/home/armiento/src/php-5.3.0/Zend/zend_hash.c:299
#29 0x00000000006bfc8e in ZEND_CATCH_SPEC_CV_HANDLER 
(execute_data=0x7fbb417b7050)
    at /home/armiento/src/php-5.3.0/Zend/zend_vm_execute.h:1234
#30 0x00000000006c0691 in execute (op_array=0x7fbb4399b558) at 
/home/armiento/src/php-5.3.0/Zend/zend_vm_execute.h:104
#31 0x000000000069eead in zend_execute_scripts (type=8, retval=0x0, 
file_count=3) at /home/armiento/src/php-5.3.0/Zend/zend.c:1188
#32 0x000000000064fbc5 in php_execute_script 
(primary_file=0x7fff4b9da0b0) at /home/armiento/src/php-
5.3.0/main/main.c:2196
#33 0x0000000000722836 in main (argc=2, argv=0x7fff4b9da318) at 
/home/armiento/src/php-5.3.0/sapi/cli/php_cli.c:1188
(gdb) 

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2009-09-23 00:54 UTC] felipe@php.net
I can't reproduce it on Debian 32bit.
libxslt 1.1.24-2 ; libxml2  2.6.32
 [2009-09-23 06:25 UTC] jani@php.net
Please try using this snapshot:

  http://snaps.php.net/php5.3-latest.tar.gz
 
For Windows:

  http://windows.php.net/snapshots/


 [2009-09-23 07:56 UTC] aldo at armiento dot com
Latest snapshot (php5.3-200909230630):

(gdb) r
Starting program: /home/armiento/env/spider/bin/php test_segfault.php
[Thread debugging using libthread_db enabled]
[New Thread 139866082309840 (LWP 1958)]
Exception!
Exception!
*** glibc detected *** free(): invalid pointer: 0x00000000019a65e0 ***

Program received signal SIGABRT, Aborted.
[Switching to Thread 139866082309840 (LWP 1958)]
0x00007f351ac7607b in raise () from /lib/libc.so.6
(gdb) bt
#0  0x00007f351ac7607b in raise () from /lib/libc.so.6
#1  0x00007f351ac7784e in abort () from /lib/libc.so.6
#2  0x00007f351acac5f9 in __fsetlocking () from /lib/libc.so.6
#3  0x00007f351acb3163 in mallopt () from /lib/libc.so.6
#4  0x00007f351acb31ee in free () from /lib/libc.so.6
#5  0x000000000044f3bb in php_libxml_node_decrement_resource (object=0x7f351c24b730)
    at /home/armiento/src/php5.3-200909230630/ext/libxml/libxml.c:1058
#6  0x00000000004cc3a5 in dom_objects_free_storage (object=0x7f351c24b730)
    at /home/armiento/src/php5.3-200909230630/ext/dom/php_dom.c:1017
#7  0x00000000006c0d56 in zend_objects_store_del_ref_by_handle_ex (handle=3, handlers=<value optimized out>)
    at /home/armiento/src/php5.3-200909230630/Zend/zend_objects_API.c:220
#8  0x00000000006c0d92 in zend_objects_store_del_ref (zobject=0x7f351c249510)
    at /home/armiento/src/php5.3-200909230630/Zend/zend_objects_API.c:172
#9  0x0000000000694795 in _zval_ptr_dtor (zval_ptr=0x7f351c24be60)
    at /home/armiento/src/php5.3-200909230630/Zend/zend_variables.h:35
#10 0x00000000006ac7e8 in zend_hash_destroy (ht=0x7f351c24bda0) at /home/armiento/src/php5.3-200909230630/Zend/zend_hash.c:526
#11 0x00000000006a08a6 in _zval_dtor_func (zvalue=0x7f351c24bd70)
    at /home/armiento/src/php5.3-200909230630/Zend/zend_variables.c:43
#12 0x0000000000694795 in _zval_ptr_dtor (zval_ptr=0x7f351c24beb8)
    at /home/armiento/src/php5.3-200909230630/Zend/zend_variables.h:35
#13 0x00000000006ac7e8 in zend_hash_destroy (ht=0x7f351c24bcc8) at /home/armiento/src/php5.3-200909230630/Zend/zend_hash.c:526
#14 0x00000000006a08a6 in _zval_dtor_func (zvalue=0x7f351c24bc98)
    at /home/armiento/src/php5.3-200909230630/Zend/zend_variables.c:43
#15 0x0000000000694795 in _zval_ptr_dtor (zval_ptr=0x7f351c24bf10)
    at /home/armiento/src/php5.3-200909230630/Zend/zend_variables.h:35
#16 0x00000000006ac7e8 in zend_hash_destroy (ht=0x7f351c24bbc0) at /home/armiento/src/php5.3-200909230630/Zend/zend_hash.c:526
#17 0x00000000006a08a6 in _zval_dtor_func (zvalue=0x7f351c24bb90)
    at /home/armiento/src/php5.3-200909230630/Zend/zend_variables.c:43
#18 0x0000000000694795 in _zval_ptr_dtor (zval_ptr=0x7f351c24bf70)
    at /home/armiento/src/php5.3-200909230630/Zend/zend_variables.h:35
#19 0x00000000006ac7e8 in zend_hash_destroy (ht=0x7f351c24bae8) at /home/armiento/src/php5.3-200909230630/Zend/zend_hash.c:526
#20 0x00000000006a08a6 in _zval_dtor_func (zvalue=0x7f351c24b110)
    at /home/armiento/src/php5.3-200909230630/Zend/zend_variables.c:43
#21 0x0000000000694795 in _zval_ptr_dtor (zval_ptr=0x7f351c24ba28)
    at /home/armiento/src/php5.3-200909230630/Zend/zend_variables.h:35
#22 0x00000000006ac7e8 in zend_hash_destroy (ht=0x7f351c24b950) at /home/armiento/src/php5.3-200909230630/Zend/zend_hash.c:526
#23 0x00000000006bd6b9 in zend_object_std_dtor (object=0x7f351c24b7a0)
    at /home/armiento/src/php5.3-200909230630/Zend/zend_objects.c:45
#24 0x00000000006bd6d9 in zend_objects_free_object_storage (object=0x7a6)
    at /home/armiento/src/php5.3-200909230630/Zend/zend_objects.c:114
#25 0x00000000006c0d56 in zend_objects_store_del_ref_by_handle_ex (handle=7, handlers=<value optimized out>)
    at /home/armiento/src/php5.3-200909230630/Zend/zend_objects_API.c:220
#26 0x00000000006c0d92 in zend_objects_store_del_ref (zobject=0x7f351c24c6a0)
    at /home/armiento/src/php5.3-200909230630/Zend/zend_objects_API.c:172
#27 0x0000000000694795 in _zval_ptr_dtor (zval_ptr=0x7f351c24b1d8)
    at /home/armiento/src/php5.3-200909230630/Zend/zend_variables.h:35
#28 0x00000000006ae457 in _zend_hash_quick_add_or_update (ht=0xcfc5e8, arKey=0x7f351c249380 "e", nKeyLength=2, h=5863242, 
    pData=0xcfc830, nDataSize=8, pDest=0x7f351a062118, flag=1) at /home/armiento/src/php5.3-200909230630/Zend/zend_hash.c:299
#29 0x00000000006c1f2e in ZEND_CATCH_SPEC_CV_HANDLER (execute_data=0x7f351a062050)
    at /home/armiento/src/php5.3-200909230630/Zend/zend_vm_execute.h:1234
#30 0x00000000006c2bd1 in execute (op_array=0x7f351c246578) at /home/armiento/src/php5.3-200909230630/Zend/zend_vm_execute.h:104
#31 0x00000000006a0b1d in zend_execute_scripts (type=8, retval=0x0, file_count=3)
    at /home/armiento/src/php5.3-200909230630/Zend/zend.c:1188
#32 0x00000000006515f5 in php_execute_script (primary_file=0x7fff24282950)
    at /home/armiento/src/php5.3-200909230630/main/main.c:2214
#33 0x00000000007248f6 in main (argc=2, argv=0x7fff24282bb8) at /home/armiento/src/php5.3-200909230630/sapi/cli/php_cli.c:1190
(gdb)
 [2009-09-25 22:22 UTC] jani@php.net
Please don't spam the bug system, one time is enough. Also, there's no 
need to add the backtrace especially when it's basically identical to 
the first one. 
 [2009-09-25 22:47 UTC] aldo at armiento dot com
Dear Mr. Jani,

my intermediate backtrace was in replying to felipe@php.net that says 
that he can't reproduce it on Debian 32bit with libxslt 1.1.24-2 and 
libxml2  2.6.32.

I installed a Debian Lenny 32bit from scratch to verify this affirmation 
and I can reproduce it.

Best regards,
A.
 [2010-06-21 23:51 UTC] felipe@php.net
I can reproduce it now. Probably I forgot to create the doc.xml to test it in the first time.
 [2010-06-22 00:19 UTC] felipe@php.net
-PHP Version: 5.*, 6 (2009-09-23) +PHP Version: 5.*
 [2010-06-22 00:19 UTC] felipe@php.net
Interesting, it cannot be reproduced on trunk.
 [2013-12-02 11:21 UTC] mike@php.net
Automatic comment on behalf of mike
Revision: http://git.php.net/?p=php-src.git;a=commit;h=6408a1a59e6d371cd488687e28e18815ea97984e
Log: fix bug #49634x
 [2013-12-02 11:29 UTC] mike@php.net
-Status: Open +Status: Closed -Assigned To: +Assigned To: mike
 [2013-12-02 16:51 UTC] ab@php.net
Automatic comment on behalf of mike
Revision: http://git.php.net/?p=php-src.git;a=commit;h=6408a1a59e6d371cd488687e28e18815ea97984e
Log: fix bug #49634x
 [2014-10-07 23:16 UTC] stas@php.net
Automatic comment on behalf of mike
Revision: http://git.php.net/?p=php-src-security.git;a=commit;h=6408a1a59e6d371cd488687e28e18815ea97984e
Log: fix bug #49634x
 [2014-10-07 23:27 UTC] stas@php.net
Automatic comment on behalf of mike
Revision: http://git.php.net/?p=php-src-security.git;a=commit;h=6408a1a59e6d371cd488687e28e18815ea97984e
Log: fix bug #49634x
 [2014-12-26 13:04 UTC] dmitry dot koterov at gmail dot com
Seems to me, this fix reduces the performance greatly. Let's review your fix again:
https://github.com/php/php-src/commit/6408a1a59e6d371cd488687e28e18815ea97984e#diff-258cc1cabc37df15d7f0ed40924f64efL281

Note that xmlDocCopyNodeList() does "a recursive copy of the node list": http://xmlsoft.org/html/libxml-tree.html#xmlDocCopyNodeList

E.g. if I have a 10MB XML document and call

<xsl:value-of select="php:function('someFunction', /, 'abc')" />

in an XSLT, the whole 10M XML document will be copied before calling someFunction(). It hasn't been copied in PHP 5.3, so we have a significant performance penalty here.

Is there another way to achieve the same behavior with no libxml2 node cloning?
 [2015-07-13 23:04 UTC] mplomer at gmx dot de
I can confirm the performance problem. My script processes bigger XML-files and makes much use of PHP function calls inside XSL and passes references to nodes to them.
After upgrading to PHP version 5.6.11, the script hits the 2 GB memory limit and sometimes segfaults - with the old PHP version it uses max 20-40 MB memory. (Version until 5.4.23 worked fine, starting with 5.4.24 not; maybe the same somewhere in 5.6 branch)

Seems to be also a memleak here ...
 [2015-07-14 18:58 UTC] mplomer at gmx dot de
As this bug is already closed, I opened a new one: Bug #70078
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Nov 21 09:01:32 2024 UTC