Bug #52001 [Com]: Memory allocation problems after using variable variables
Edit report at http://bugs.php.net/bug.php?id=52001&edit=1 ID: 52001 Comment by: boldin dot pavel at gmail dot com Reported by: lisio at bk dot ru Summary: Memory allocation problems after using variable variables Status: Open Type: Bug Package: Scripting Engine problem Operating System: Linux PHP Version: 5.3.2 New Comment: Even more: f($$var, 0) will also work. If you declare function before calling it will work too. Seems like bug in zend_do_pass_params or so on, causing to corruption of buffer. These CVs are just missing from the scope (active_symbol_table) after calling function. Seems like they are removed in middle of code execution. Previous Comments: [2010-06-06 09:10:39] akorolyov at gmail dot com In this case I receive correct result. [2010-06-05 17:14:28] lisio at bk dot ru Description: After calling the function using a non-defined variable variable as a second parameter the interpreter goes crazy. Just reproduce the script on any of 5.3.* versions of PHP. Test script: --- Expected result: 1 Actual result: -- 2 -- Edit this bug report at http://bugs.php.net/bug.php?id=52001&edit=1
Bug #52001 [Com]: Memory allocation problems after using variable variables
Edit report at http://bugs.php.net/bug.php?id=52001&edit=1 ID: 52001 Comment by: boldin dot pavel at gmail dot com Reported by: lisio at bk dot ru Summary: Memory allocation problems after using variable variables Status: Open Type: Bug Package: Scripting Engine problem Operating System: Linux PHP Version: 5.3.2 New Comment: More detailed: when you pass off the function, _get_zval_cv_lookup no longer able to find your CVs, and they are missed. _get_zval_cv_lookup then returns pointer EG(uninitialized_zval_ptr), which is shared among a set of values. So two values are stored in same place. It is essential that this happens only if you call it with ZEND_FCALL_BY_NAME (i.e. declare after using) and only if dereferenced value is not first. Previous Comments: [2010-06-06 10:30:54] boldin dot pavel at gmail dot com Even more: f($$var, 0) will also work. If you declare function before calling it will work too. Seems like bug in zend_do_pass_params or so on, causing to corruption of buffer. These CVs are just missing from the scope (active_symbol_table) after calling function. Seems like they are removed in middle of code execution. [2010-06-06 09:10:39] akorolyov at gmail dot com In this case I receive correct result. [2010-06-05 17:14:28] lisio at bk dot ru Description: After calling the function using a non-defined variable variable as a second parameter the interpreter goes crazy. Just reproduce the script on any of 5.3.* versions of PHP. Test script: --- Expected result: 1 Actual result: -- 2 -- Edit this bug report at http://bugs.php.net/bug.php?id=52001&edit=1
Bug #52001 [Com]: Memory allocation problems after using variable variables
Edit report at http://bugs.php.net/bug.php?id=52001&edit=1 ID: 52001 Comment by: boldin dot pavel at gmail dot com Reported by: lisio at bk dot ru Summary: Memory allocation problems after using variable variables Status: Open Type: Bug Package: Scripting Engine problem Operating System: Linux PHP Version: 5.3.2 New Comment: Here is the problem: Zend/zend_execution.c line 703 (version 5.3.2): incorrect reference count (== 1) in case of bug. Should be == 3 and copy data in 'else' branch. Previous Comments: [2010-06-06 10:36:36] boldin dot pavel at gmail dot com More detailed: when you pass off the function, _get_zval_cv_lookup no longer able to find your CVs, and they are missed. _get_zval_cv_lookup then returns pointer EG(uninitialized_zval_ptr), which is shared among a set of values. So two values are stored in same place. It is essential that this happens only if you call it with ZEND_FCALL_BY_NAME (i.e. declare after using) and only if dereferenced value is not first. [2010-06-06 10:30:54] boldin dot pavel at gmail dot com Even more: f($$var, 0) will also work. If you declare function before calling it will work too. Seems like bug in zend_do_pass_params or so on, causing to corruption of buffer. These CVs are just missing from the scope (active_symbol_table) after calling function. Seems like they are removed in middle of code execution. [2010-06-06 09:10:39] akorolyov at gmail dot com In this case I receive correct result. [2010-06-05 17:14:28] lisio at bk dot ru Description: After calling the function using a non-defined variable variable as a second parameter the interpreter goes crazy. Just reproduce the script on any of 5.3.* versions of PHP. Test script: --- Expected result: 1 Actual result: -- 2 -- Edit this bug report at http://bugs.php.net/bug.php?id=52001&edit=1
Bug #52001 [Com]: Memory allocation problems after using variable variables
Edit report at http://bugs.php.net/bug.php?id=52001&edit=1 ID: 52001 Comment by: boldin dot pavel at gmail dot com Reported by: lisio at bk dot ru Summary: Memory allocation problems after using variable variables Status: Open Type: Bug Package: Scripting Engine problem Operating System: Linux PHP Version: 5.3.2 New Comment: Version without bug: (gdb) zend_send_by_var_helper_SPEC_VAR (execute_data=0x88a28d0) at /home/davinchi/php-5.3.2/Zend/zend_vm_execute.h:8257 8257varptr = _get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC); (gdb) 8259if (varptr == &EG(uninitialized_zval)) { (gdb) p varptr $24 = (zval *) 0x877fd04 (gdb) p &executor_globals.uninitialized_zval $25 = (zval *) 0x877fd04 (gdb) p executor_globals.uninitialized_zval_ptr $26 = (zval *) 0x877fd04 And version with bug: zend_send_by_var_helper_SPEC_VAR (execute_data=0x88a28d0) at /home/davinchi/php-5.3.2/Zend/zend_vm_execute.h:8254 8254zend_op *opline = EX(opline); (gdb) 8257varptr = _get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC); (gdb) n 8259if (varptr == &EG(uninitialized_zval)) { (gdb) p varptr $27 = (zval *) 0x8876d8c (gdb) p &executor_globals.uninitialized_zval $28 = (zval *) 0x877fd04 (gdb) p executor_globals.uninitialized_zval_ptr $29 = (zval *) 0x8876d8c See that uninitialized_zval_ptr dont pointers to the uninitialized_zval at all! Previous Comments: ------------ [2010-06-06 11:23:47] boldin dot pavel at gmail dot com Here is the problem: Zend/zend_execution.c line 703 (version 5.3.2): incorrect reference count (== 1) in case of bug. Should be == 3 and copy data in 'else' branch. -------------------- [2010-06-06 10:36:36] boldin dot pavel at gmail dot com More detailed: when you pass off the function, _get_zval_cv_lookup no longer able to find your CVs, and they are missed. _get_zval_cv_lookup then returns pointer EG(uninitialized_zval_ptr), which is shared among a set of values. So two values are stored in same place. It is essential that this happens only if you call it with ZEND_FCALL_BY_NAME (i.e. declare after using) and only if dereferenced value is not first. -------------------- [2010-06-06 10:30:54] boldin dot pavel at gmail dot com Even more: f($$var, 0) will also work. If you declare function before calling it will work too. Seems like bug in zend_do_pass_params or so on, causing to corruption of buffer. These CVs are just missing from the scope (active_symbol_table) after calling function. Seems like they are removed in middle of code execution. [2010-06-06 09:10:39] akorolyov at gmail dot com In this case I receive correct result. [2010-06-05 17:14:28] lisio at bk dot ru Description: After calling the function using a non-defined variable variable as a second parameter the interpreter goes crazy. Just reproduce the script on any of 5.3.* versions of PHP. Test script: --- Expected result: 1 Actual result: -- 2 -- Edit this bug report at http://bugs.php.net/bug.php?id=52001&edit=1
Bug #52001 [Com]: Memory allocation problems after using variable variables
Edit report at http://bugs.php.net/bug.php?id=52001&edit=1 ID: 52001 Comment by: boldin dot pavel at gmail dot com Reported by: lisio at bk dot ru Summary: Memory allocation problems after using variable variables Status: Open Type: Bug Package: Scripting Engine problem Operating System: Linux PHP Version: 5.3.2 New Comment: Finally: bug is at if (opline->extended_value & ZEND_FETCH_MAKE_REF) { SEPARATE_ZVAL_TO_MAKE_IS_REF(retval); } SEPARATE_ZVAL_TO_MAKE_IS_REF seems to ruine *retval (which is executor_globals.uninitialized_ptr). Then this leads to incorrectly working zend_send_by_var_helper and incorrect referencing count in zend_assign_to_variable. Trying to patch now. Previous Comments: [2010-06-06 18:08:56] boldin dot pavel at gmail dot com Version without bug: (gdb) zend_send_by_var_helper_SPEC_VAR (execute_data=0x88a28d0) at /home/davinchi/php-5.3.2/Zend/zend_vm_execute.h:8257 8257varptr = _get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC); (gdb) 8259if (varptr == &EG(uninitialized_zval)) { (gdb) p varptr $24 = (zval *) 0x877fd04 (gdb) p &executor_globals.uninitialized_zval $25 = (zval *) 0x877fd04 (gdb) p executor_globals.uninitialized_zval_ptr $26 = (zval *) 0x877fd04 And version with bug: zend_send_by_var_helper_SPEC_VAR (execute_data=0x88a28d0) at /home/davinchi/php-5.3.2/Zend/zend_vm_execute.h:8254 8254zend_op *opline = EX(opline); (gdb) 8257varptr = _get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC); (gdb) n 8259if (varptr == &EG(uninitialized_zval)) { (gdb) p varptr $27 = (zval *) 0x8876d8c (gdb) p &executor_globals.uninitialized_zval $28 = (zval *) 0x877fd04 (gdb) p executor_globals.uninitialized_zval_ptr $29 = (zval *) 0x8876d8c See that uninitialized_zval_ptr dont pointers to the uninitialized_zval at all! ---------------- [2010-06-06 11:23:47] boldin dot pavel at gmail dot com Here is the problem: Zend/zend_execution.c line 703 (version 5.3.2): incorrect reference count (== 1) in case of bug. Should be == 3 and copy data in 'else' branch. ------------------------ [2010-06-06 10:36:36] boldin dot pavel at gmail dot com More detailed: when you pass off the function, _get_zval_cv_lookup no longer able to find your CVs, and they are missed. _get_zval_cv_lookup then returns pointer EG(uninitialized_zval_ptr), which is shared among a set of values. So two values are stored in same place. It is essential that this happens only if you call it with ZEND_FCALL_BY_NAME (i.e. declare after using) and only if dereferenced value is not first. ------------------------ [2010-06-06 10:30:54] boldin dot pavel at gmail dot com Even more: f($$var, 0) will also work. If you declare function before calling it will work too. Seems like bug in zend_do_pass_params or so on, causing to corruption of buffer. These CVs are just missing from the scope (active_symbol_table) after calling function. Seems like they are removed in middle of code execution. [2010-06-06 09:10:39] akorolyov at gmail dot com In this case I receive correct result. 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/bug.php?id=52001 -- Edit this bug report at http://bugs.php.net/bug.php?id=52001&edit=1
Bug #52001 [Com]: Memory allocation problems after using variable variables
Edit report at http://bugs.php.net/bug.php?id=52001&edit=1 ID: 52001 Comment by: boldin dot pavel at gmail dot com Reported by: lisio at bk dot ru Summary: Memory allocation problems after using variable variables Status: Open Type: Bug Package: Scripting Engine problem Operating System: Linux PHP Version: 5.3.2 New Comment: I have attached patch. It must be reviewed by professional PHP developer. For me it is clearly that call of SEPARATE_ZVAL_TO_MAKE_IS_REF must be predicated with such a check (and it is done in all other cases). Previous Comments: [2010-06-06 18:38:05] boldin dot pavel at gmail dot com Finally: bug is at if (opline->extended_value & ZEND_FETCH_MAKE_REF) { SEPARATE_ZVAL_TO_MAKE_IS_REF(retval); } SEPARATE_ZVAL_TO_MAKE_IS_REF seems to ruine *retval (which is executor_globals.uninitialized_ptr). Then this leads to incorrectly working zend_send_by_var_helper and incorrect referencing count in zend_assign_to_variable. Trying to patch now. [2010-06-06 18:08:56] boldin dot pavel at gmail dot com Version without bug: (gdb) zend_send_by_var_helper_SPEC_VAR (execute_data=0x88a28d0) at /home/davinchi/php-5.3.2/Zend/zend_vm_execute.h:8257 8257varptr = _get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC); (gdb) 8259if (varptr == &EG(uninitialized_zval)) { (gdb) p varptr $24 = (zval *) 0x877fd04 (gdb) p &executor_globals.uninitialized_zval $25 = (zval *) 0x877fd04 (gdb) p executor_globals.uninitialized_zval_ptr $26 = (zval *) 0x877fd04 And version with bug: zend_send_by_var_helper_SPEC_VAR (execute_data=0x88a28d0) at /home/davinchi/php-5.3.2/Zend/zend_vm_execute.h:8254 8254zend_op *opline = EX(opline); (gdb) 8257varptr = _get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC); (gdb) n 8259if (varptr == &EG(uninitialized_zval)) { (gdb) p varptr $27 = (zval *) 0x8876d8c (gdb) p &executor_globals.uninitialized_zval $28 = (zval *) 0x877fd04 (gdb) p executor_globals.uninitialized_zval_ptr $29 = (zval *) 0x8876d8c See that uninitialized_zval_ptr dont pointers to the uninitialized_zval at all! ---------------- [2010-06-06 11:23:47] boldin dot pavel at gmail dot com Here is the problem: Zend/zend_execution.c line 703 (version 5.3.2): incorrect reference count (== 1) in case of bug. Should be == 3 and copy data in 'else' branch. ------------------------ [2010-06-06 10:36:36] boldin dot pavel at gmail dot com More detailed: when you pass off the function, _get_zval_cv_lookup no longer able to find your CVs, and they are missed. _get_zval_cv_lookup then returns pointer EG(uninitialized_zval_ptr), which is shared among a set of values. So two values are stored in same place. It is essential that this happens only if you call it with ZEND_FCALL_BY_NAME (i.e. declare after using) and only if dereferenced value is not first. ------------------------ [2010-06-06 10:30:54] boldin dot pavel at gmail dot com Even more: f($$var, 0) will also work. If you declare function before calling it will work too. Seems like bug in zend_do_pass_params or so on, causing to corruption of buffer. These CVs are just missing from the scope (active_symbol_table) after calling function. Seems like they are removed in middle of code execution. 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/bug.php?id=52001 -- Edit this bug report at http://bugs.php.net/bug.php?id=52001&edit=1
Bug #52001 [Com]: Memory allocation problems after using variable variables
Edit report at http://bugs.php.net/bug.php?id=52001&edit=1 ID: 52001 Comment by: boldin dot pavel at gmail dot com Reported by: lisio at bk dot ru Summary: Memory allocation problems after using variable variables Status: Open Type: Bug Package: Scripting Engine problem Operating System: Linux PHP Version: 5.3.2 New Comment: Zend/zend_compile.c 1066: if (opline && type == BP_VAR_W && arg_offset) { opline->extended_value = ZEND_FETCH_MAKE_REF; } Is not this bug too? ZEND_FETCH_MAKE_REF is not set for first (arg_offset == 0) arg? Previous Comments: [2010-06-06 19:06:29] boldin dot pavel at gmail dot com I have attached patch. It must be reviewed by professional PHP developer. For me it is clearly that call of SEPARATE_ZVAL_TO_MAKE_IS_REF must be predicated with such a check (and it is done in all other cases). [2010-06-06 18:38:05] boldin dot pavel at gmail dot com Finally: bug is at if (opline->extended_value & ZEND_FETCH_MAKE_REF) { SEPARATE_ZVAL_TO_MAKE_IS_REF(retval); } SEPARATE_ZVAL_TO_MAKE_IS_REF seems to ruine *retval (which is executor_globals.uninitialized_ptr). Then this leads to incorrectly working zend_send_by_var_helper and incorrect referencing count in zend_assign_to_variable. Trying to patch now. ---- [2010-06-06 18:08:56] boldin dot pavel at gmail dot com Version without bug: (gdb) zend_send_by_var_helper_SPEC_VAR (execute_data=0x88a28d0) at /home/davinchi/php-5.3.2/Zend/zend_vm_execute.h:8257 8257varptr = _get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC); (gdb) 8259if (varptr == &EG(uninitialized_zval)) { (gdb) p varptr $24 = (zval *) 0x877fd04 (gdb) p &executor_globals.uninitialized_zval $25 = (zval *) 0x877fd04 (gdb) p executor_globals.uninitialized_zval_ptr $26 = (zval *) 0x877fd04 And version with bug: zend_send_by_var_helper_SPEC_VAR (execute_data=0x88a28d0) at /home/davinchi/php-5.3.2/Zend/zend_vm_execute.h:8254 8254zend_op *opline = EX(opline); (gdb) 8257varptr = _get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC); (gdb) n 8259if (varptr == &EG(uninitialized_zval)) { (gdb) p varptr $27 = (zval *) 0x8876d8c (gdb) p &executor_globals.uninitialized_zval $28 = (zval *) 0x877fd04 (gdb) p executor_globals.uninitialized_zval_ptr $29 = (zval *) 0x8876d8c See that uninitialized_zval_ptr dont pointers to the uninitialized_zval at all! ------------------------ [2010-06-06 11:23:47] boldin dot pavel at gmail dot com Here is the problem: Zend/zend_execution.c line 703 (version 5.3.2): incorrect reference count (== 1) in case of bug. Should be == 3 and copy data in 'else' branch. ------------------------ [2010-06-06 10:36:36] boldin dot pavel at gmail dot com More detailed: when you pass off the function, _get_zval_cv_lookup no longer able to find your CVs, and they are missed. _get_zval_cv_lookup then returns pointer EG(uninitialized_zval_ptr), which is shared among a set of values. So two values are stored in same place. It is essential that this happens only if you call it with ZEND_FCALL_BY_NAME (i.e. declare after using) and only if dereferenced value is not first. 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/bug.php?id=52001 -- Edit this bug report at http://bugs.php.net/bug.php?id=52001&edit=1
Bug #51886 [Com]: call_user_func() does not propagate the scope
Edit report at http://bugs.php.net/bug.php?id=51886&edit=1 ID: 51886 Comment by: boldin dot pavel at gmail dot com Reported by: vesko at webstudiobulgaria dot com Summary: call_user_func() does not propagate the scope Status: Open Type: Bug Package: Scripting Engine problem Operating System: Debian 5.0 PHP Version: 5.3SVN-2010-05-22 (snap) New Comment: Simple patch attached. Works, but can cause side effects. Previous Comments: [2010-05-25 09:58:16] vesko at webstudiobulgaria dot com well, yes or no it has to be consistent. My personal opinion is also that $this should not be defined, but as I quoted it above according PHP 5.3 policy it should say yes. [2010-05-25 09:06:41] m...@php.net doh! From my understanding, this should say "no" *all* 4 times. There's no t2 instance. [2010-05-22 16:10:50] vesko at webstudiobulgaria dot com Description: call_user_func() does not propagate the scope when used in calls between two classes that have no child-parent relation. When they have child-parent relation as described in this bug entry: http://bugs.php.net/bug.php?id=47402 it is fine. As it is put in the "Backward Incompatible Changes" here: http://www.php.net/manual/en/migration53.incompatible.php "The call_user_func() family of functions now propagate $this even if the callee is a parent class. ". I guess it has to do it for classes that have no relation as well (or if not so the direct call t2::some_method() should not do it either). As it is at the moment is inconsistent. P.S. As well I think a better explanation with an example in the docs should be added for "The call_user_func() family of functions now propagate $this even if the callee is a parent class.". It is not clear at all what it is about if one don't get onto the original bug entry: "http://bugs.php.net/bug.php?id=47402";. I didnt use the original 47402 entry as in fact it is not a bug. Test script: --- class t1 { public function __call($method,$args) { //call_user_func('t2::some_method',$args);//for PHP 5.3 call_user_func(array('t2','some_method'),$args); t2::some_method(); } public function existing_method() { //call_user_func('t2::some_method');//for PHP 5.3 call_user_func(array('t2','some_method')); t2::some_method(); } } class t2 { public function some_method() { print isset($this)?'yes':'no'; print PHP_EOL; } } $t1 = new t1; $t1->existing_method(); $t1->non_existing_method();//use overloading Expected result: yes yes yes yes Actual result: -- no yes no yes -- Edit this bug report at http://bugs.php.net/bug.php?id=51886&edit=1
Bug #52001 [Com]: Memory allocation problems after using variable variables
Edit report at http://bugs.php.net/bug.php?id=52001&edit=1 ID: 52001 Comment by: boldin dot pavel at gmail dot com Reported by: lisio at bk dot ru Summary: Memory allocation problems after using variable variables Status: Assigned Type: Bug Package: Scripting Engine problem Operating System: Linux PHP Version: 5.3.2 Assigned To: dmitry New Comment: old patch brokes tests (Zend/tests/objects_020.phpt), new one don't. Still don't sure if it is absolutely correct. Previous Comments: [2010-06-06 19:15:45] boldin dot pavel at gmail dot com Zend/zend_compile.c 1066: if (opline && type == BP_VAR_W && arg_offset) { opline->extended_value = ZEND_FETCH_MAKE_REF; } Is not this bug too? ZEND_FETCH_MAKE_REF is not set for first (arg_offset == 0) arg? -------- [2010-06-06 19:06:29] boldin dot pavel at gmail dot com I have attached patch. It must be reviewed by professional PHP developer. For me it is clearly that call of SEPARATE_ZVAL_TO_MAKE_IS_REF must be predicated with such a check (and it is done in all other cases). -------- [2010-06-06 18:38:05] boldin dot pavel at gmail dot com Finally: bug is at if (opline->extended_value & ZEND_FETCH_MAKE_REF) { SEPARATE_ZVAL_TO_MAKE_IS_REF(retval); } SEPARATE_ZVAL_TO_MAKE_IS_REF seems to ruine *retval (which is executor_globals.uninitialized_ptr). Then this leads to incorrectly working zend_send_by_var_helper and incorrect referencing count in zend_assign_to_variable. Trying to patch now. ------------ [2010-06-06 18:08:56] boldin dot pavel at gmail dot com Version without bug: (gdb) zend_send_by_var_helper_SPEC_VAR (execute_data=0x88a28d0) at /home/davinchi/php-5.3.2/Zend/zend_vm_execute.h:8257 8257varptr = _get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC); (gdb) 8259if (varptr == &EG(uninitialized_zval)) { (gdb) p varptr $24 = (zval *) 0x877fd04 (gdb) p &executor_globals.uninitialized_zval $25 = (zval *) 0x877fd04 (gdb) p executor_globals.uninitialized_zval_ptr $26 = (zval *) 0x877fd04 And version with bug: zend_send_by_var_helper_SPEC_VAR (execute_data=0x88a28d0) at /home/davinchi/php-5.3.2/Zend/zend_vm_execute.h:8254 8254zend_op *opline = EX(opline); (gdb) 8257varptr = _get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC); (gdb) n 8259if (varptr == &EG(uninitialized_zval)) { (gdb) p varptr $27 = (zval *) 0x8876d8c (gdb) p &executor_globals.uninitialized_zval $28 = (zval *) 0x877fd04 (gdb) p executor_globals.uninitialized_zval_ptr $29 = (zval *) 0x8876d8c See that uninitialized_zval_ptr dont pointers to the uninitialized_zval at all! ------------------------ [2010-06-06 11:23:47] boldin dot pavel at gmail dot com Here is the problem: Zend/zend_execution.c line 703 (version 5.3.2): incorrect reference count (== 1) in case of bug. Should be == 3 and copy data in 'else' branch. 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/bug.php?id=52001 -- Edit this bug report at http://bugs.php.net/bug.php?id=52001&edit=1