|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
[2012-01-09 06:16 UTC] valentiny510 at yahoo dot es
Description:
------------
If you try to return $this double quoted in __toString break all the system and does not even throw any exception or log anything.
my php.ini have
error_reporting = E_ALL | E_STRICT
display_errors = On
display_startup_errors = On
log_errors = On
report_memleaks = On
report_zend_debug = 1
Test script:
---------------
class test
{
public function __toString ( )
{
return "$this";
}
}
$test = new test;
echo $test;
Expected result:
----------------
the string "$this" or the error exception
Actual result:
--------------
The server break completely and does not output nothing, not even the error log.
The browser say "The connection has been reset".
(The apache server is still logging the requests)
PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits
|
|||||||||||||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Sun Dec 14 22:00:01 2025 UTC |
Confirmed for 5.3.8 and for 2011/01/04 snapshots of 5.3, 5.4 and trunk, on Arch64. Inifnite recursion causing SIGSEGV. Partial backtrace: ----------- BEGIN BACKTRACE ----------- #0 0x00000000005d853e in zend_mm_search_large_block (heap= Cannot access memory at address 0x7fffff7fefc0 ) at src-trunk/Zend/zend_alloc.c:1804 #1 0x00000000005d8a50 in _zend_mm_alloc_int (heap=0xad72b0, size=32, __zend_filename=0x86c908 "src-trunk/Zend/zend.c", __zend_lineno=264, __zend_orig_filename=0x0, __zend_orig_lineno=0) at src-trunk/Zend/zend_alloc.c:1934 #2 0x00000000005da624 in _emalloc (size=32, __zend_filename=0x86c908 "src-trunk/Zend/zend.c", __zend_lineno=264, __zend_orig_filename=0x0, __zend_orig_lineno=0) at src-trunk/Zend/zend_alloc.c:2425 #3 0x000000000060dfd9 in zend_make_printable_zval (expr=0x7ffff6777618, expr_copy=0x7fffff7ff220, use_copy=0x7fffff7ff21c) at src-trunk/Zend/zend.c:264 #4 0x0000000000712d75 in ZEND_ADD_VAR_SPEC_UNUSED_CV_HANDLER ( execute_data=0x7ffff6710510) at src-trunk/Zend/zend_vm_execute.h:25868 #5 0x000000000064e123 in execute (op_array=0x7ffff7fcbf68) at src-trunk/Zend/zend_vm_execute.h:410 #6 0x00000000005fd1de in zend_call_function (fci=0x7fffff7ff6e0, fci_cache=0x7fffff7ff670) at src-trunk/Zend/zend_execute_API.c:958 #7 0x000000000062edc1 in zend_call_method (object_pp=0x7fffff7ff798, obj_ce=0x7ffff7fcab98, fn_proxy=0x7ffff7fcad00, function_name=0x872790 "__tostring", function_name_len=10, retval_ptr_ptr=0x7fffff7ff7a8, param_count=0, arg1=0x0, arg2=0x0) at src-trunk/Zend/zend_interfaces.c:97 #8 0x00000000006462e8 in zend_std_cast_object_tostring (readobj=0x7ffff6777618, writeobj=0x7fffff7ff960, type=6) at src-trunk/Zend/zend_object_handlers.c:1494 #9 0x000000000060e0b4 in zend_make_printable_zval (expr=0x7ffff6801598, expr_copy=0x7fffff7ff960, use_copy=0x7fffff7ff95c) at src-trunk/Zend/zend.c:267 #10 0x0000000000712d75 in ZEND_ADD_VAR_SPEC_UNUSED_CV_HANDLER ( execute_data=0x7ffff6710428) at src-trunk/Zend/zend_vm_execute.h:25868 #11 0x000000000064e123 in execute (op_array=0x7ffff7fcbf68) at src-trunk/Zend/zend_vm_execute.h:410 #12 0x00000000005fd1de in zend_call_function (fci=0x7fffff7ffe20, fci_cache=0x7fffff7ffdb0) at src-trunk/Zend/zend_execute_API.c:958 (#7-#12 repeats) ------------ END BACKTRACE ------------Looking into the source (zend_object_handlers.c) you don“t need the debugger: ZEND_API int zend_std_cast_object_tostring(zval *readobj, zval *writeobj, int type TSRMLS_DC) /* {{{ */ { zval *retval; zend_class_entry *ce; switch (type) { case IS_STRING: ce = Z_OBJCE_P(readobj); if (ce->__tostring && (zend_call_method_with_0_params(&readobj, ce, &ce->__tostring, "__tostring", &retval) || EG(exception))) { if (EG(exception)) { if (retval) { zval_ptr_dtor(&retval); } zend_error(E_ERROR, "Method %s::__toString() must not throw an exception", ce->name); return FAILURE; } if (Z_TYPE_P(retval) == IS_STRING) { INIT_PZVAL(writeobj); if (readobj == writeobj) { zval_dtor(readobj); } ZVAL_ZVAL(writeobj, retval, 1, 1); if (Z_TYPE_P(writeobj) != type) { convert_to_explicit_type(writeobj, type); } return SUCCESS; } else { zval_ptr_dtor(&retval); INIT_PZVAL(writeobj); if (readobj == writeobj) { zval_dtor(readobj); } ZVAL_EMPTY_STRING(writeobj); zend_error(E_RECOVERABLE_ERROR, "Method %s::__toString() must return a string value", ce->name); return SUCCESS; } } return FAILURE; case IS_BOOL: INIT_PZVAL(writeobj); ZVAL_BOOL(writeobj, 1); return SUCCESS; case IS_LONG: ce = Z_OBJCE_P(readobj); zend_error(E_NOTICE, "Object of class %s could not be converted to int", ce->name); INIT_PZVAL(writeobj); if (readobj == writeobj) { zval_dtor(readobj); } ZVAL_LONG(writeobj, 1); return SUCCESS; case IS_DOUBLE: ce = Z_OBJCE_P(readobj); zend_error(E_NOTICE, "Object of class %s could not be converted to double", ce->name); INIT_PZVAL(writeobj); if (readobj == writeobj) { zval_dtor(readobj); } ZVAL_DOUBLE(writeobj, 1); return SUCCESS; default: INIT_PZVAL(writeobj); Z_TYPE_P(writeobj) = IS_NULL; break; } return FAILURE; }