|   | php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login | 
| 
  [2007-03-07 14:01 UTC] sebastian@php.net
 Description:
------------
See below.
Reproduce code:
---------------
<?php
class Mixin
{
    public function __call($message, $arguments)
    {
    }
}
class Test
{
}
runkit_method_copy('Test', '__call', 'Mixin');
$t = new Test;
$t->test();
Expected result:
----------------
No segfault.
Actual result:
--------------
sb@wopr-mobile ~ % gdb /usr/local/php-5.2-debug/bin/php
GNU gdb 6.6-debian
Copyright (C) 2006 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "i486-linux-gnu"...
Using host libthread_db library "/lib/tls/i686/cmov/libthread_db.so.1".
(gdb) r test.php
Starting program: /usr/local/php-5.2-debug/bin/php test.php
[Thread debugging using libthread_db enabled]
[New Thread -1214802240 (LWP 5576)]
Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread -1214802240 (LWP 5576)]
0xbf868c7d in ?? ()
(gdb) bt
#0  0xbf868c7d in ?? ()
#1  0x083800fd in zend_call_function (fci=0xbf868bd8, fci_cache=0xbf868bfc) at /usr/local/src/php/php-5.2/Zend/zend_execute_API.c:984
#2  0x083a43a9 in zend_call_method (object_pp=0xbf868cbc, obj_ce=0x8619440, fn_proxy=0x861955c, function_name=0x84e1780 "__call", 
    function_name_len=6, retval_ptr_ptr=0xbf868c7c, param_count=2, arg1=0x8619b20, arg2=0x8617178)
    at /usr/local/src/php/php-5.2/Zend/zend_interfaces.c:88
#3  0x083adfea in zend_std_call_user_call (ht=0, return_value=0x86171b4, return_value_ptr=0x0, this_ptr=0x86171f0, return_value_used=0)
    at /usr/local/src/php/php-5.2/Zend/zend_object_handlers.c:657
#4  0x083b1ad4 in zend_do_fcall_common_helper_SPEC (execute_data=0xbf868e70) at /usr/local/src/php/php-5.2/Zend/zend_vm_execute.h:200
#5  0x083b2721 in ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER (execute_data=0xbf868e70) at /usr/local/src/php/php-5.2/Zend/zend_vm_execute.h:322
#6  0x083b1624 in execute (op_array=0x861792c) at /usr/local/src/php/php-5.2/Zend/zend_vm_execute.h:92
#7  0x0838d14d in zend_execute_scripts (type=8, retval=0x0, file_count=3) at /usr/local/src/php/php-5.2/Zend/zend.c:1134
#8  0x0833863f in php_execute_script (primary_file=0xbf86b1c8) at /usr/local/src/php/php-5.2/main/main.c:1788
#9  0x08406ae0 in main (argc=2, argv=0xbf86b334) at /usr/local/src/php/php-5.2/sapi/cli/php_cli.c:1127
(gdb) f 1
#1  0x083800fd in zend_call_function (fci=0xbf868bd8, fci_cache=0xbf868bfc) at /usr/local/src/php/php-5.2/Zend/zend_execute_API.c:984
984                     ((zend_internal_function *) EX(function_state).function)->handler(fci->param_count, *fci->retval_ptr_ptr, EX(function_state).function->common.return_reference?fci->retval_ptr_ptr:NULL, (fci->object_pp?*fci->object_pp:NULL), 1 TSRMLS_CC);
(gdb) p *fci
$1 = {size = 36, function_table = 0x280, function_name = 0xbf868c0c, symbol_table = 0x0, retval_ptr_ptr = 0xbf868c7c, param_count = 2, 
  params = 0xbf868c1c, object_pp = 0xbf868cbc, no_separation = 1 '\001'}
(gdb) p *fci_cache
$2 = {initialized = 1 '\001', function_handler = 0xbf868bc4, calling_scope = 0x8619440, object_pp = 0xbf868cbc}
PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits             | |||||||||||||||||||||||||||
|  Copyright © 2001-2025 The PHP Group All rights reserved. | Last updated: Fri Oct 31 00:00:01 2025 UTC | 
There has been a small mistake in php_runkit_method_copy. magic methods had been registered with wrong pointer (points to the already overridden stack location instead to function in hash table) Patch follows: Index: runkit_methods.c =================================================================== RCS file: /repository/pecl/runkit/runkit_methods.c,v retrieving revision 1.7 diff -u -r1.7 runkit_methods.c --- runkit_methods.c 7 Jun 2006 17:35:33 -0000 1.7 +++ runkit_methods.c 27 Dec 2007 20:52:46 -0000 @@ -375,7 +375,7 @@ char *sclass, int sclass_len, char *sfunc, int sfunc_len TSRMLS_DC) { zend_class_entry *dce, *sce; - zend_function dfe, *sfe; + zend_function dfe, *sfe, *dfeInHashTable; if (php_runkit_fetch_class_method(sclass, sclass_len, sfunc, sfunc_len, &sce, &sfe TSRMLS_CC) == FAILURE) { return FAILURE; @@ -397,12 +397,12 @@ dfe.common.scope = dce; #endif - if (zend_hash_add(&dce->function_table, dfunc, dfunc_len + 1, &dfe, sizeof(zend_function), NULL) == FAILURE) { + if (zend_hash_add(&dce->function_table, dfunc, dfunc_len + 1, &dfe, sizeof(zend_function), &dfeInHashTable) == FAILURE) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Error adding method to class %s::%s()", dclass, dfunc); return FAILURE; } - PHP_RUNKIT_ADD_MAGIC_METHOD(dce, dfunc, &dfe); + PHP_RUNKIT_ADD_MAGIC_METHOD(dce, dfunc, dfeInHashTable); zend_hash_apply_with_arguments(EG(class_table), (apply_func_args_t)php_runkit_update_children_methods, 5, dce, dce, &dfe, dfunc, dfunc_len); Index: tests/bug10300.phpt =================================================================== RCS file: tests/bug10300.phpt diff -N tests/bug10300.phpt --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ tests/bug10300.phpt 27 Dec 2007 20:52:46 -0000 @@ -0,0 +1,27 @@ +--TEST-- +Bug #10300 Segfault when copying __call() +--SKIPIF-- +<?php if(!extension_loaded("runkit") || !RUNKIT_FEATURE_MANIPULATION) print "skip"; ?> +--INI-- +error_reporting=E_ALL +display_errors=on +--FILE-- +<?php +class Mixin +{ + public function __call($message, $arguments) + { + } +} + +class Test +{ +} + +runkit_method_copy('Test', '__call', 'Mixin'); + +$t = new Test; +$t->test(); +?> +--EXPECT-- +