Edit report at https://bugs.php.net/bug.php?id=60689&edit=1

 ID:                 60689
 Comment by:         phpmpan at mpan dot pl
 Reported by:        valentiny510 at yahoo dot es
 Summary:            Return $this double quoted __toString
 Status:             Bogus
 Type:               Bug
 Package:            Class/Object related
 Operating System:   windows xp
 PHP Version:        5.3.8
 Block user comment: N
 Private report:     N

 New Comment:

> Probably because of some faulty C code using an invalid pointer.
Nope. This is caused by faulty PHP code that valentiny510 presented us earlier. 
And it's not because of invalid pointer. As backtrace shows, it's stack 
overflow.

However I agree that setting this report to bogus without a reason is not a 
nice thing. `__toString` documentation says nothing about recursive calls. It 
only says that the return type should be a string or `E_RECOVERABLE_ERROR` 
happens. In this case this requirement is satisfied. Therefore what should we 
serach for in the manual?

While this is an obvious error in user's code, a similar situation in other 
functions does not cause a low-level crash. PHP nicely handles this and emits 
an error. But in this specific case this is not working. From PHP sources point 
of view it's obvious that different things handle those cases, but it's not so 
easy to see or expected from users point of view. Therefore this should be 
either fixed or, if fixing this would require too much work, ignoring. But 
ignoring with a specific reason of error being too hard to fix.


Previous Comments:
------------------------------------------------------------------------
[2012-01-18 09:51:56] harrygriff at griffcomp dot com

I just love when after one week somebody come and renspond with a copy/paste 
message saying is not a bug with no arguments.

My tests reveal that this script completely crush the apache server and dont't 
even warn about it. Apache logs show this line..
[Wed Jan 18 10:36:53 2012] [notice] Parent: child process exited with status 
3221225477 -- Restarting.
.......etc...
After some time investigating I found this answer..
The 3221225477 is C0000005 in hex notation, which is just the good old general 
protection fault, caught by the windows kernel.

In other words: Apache itself, some Apace module or any of the DLLs used by 
Apache or its modules crashed. Probably because of some faulty C code using an 
invalid pointer.

So if only few lines of PHP code can crush/restart the server don't tell me is 
"not a bug"... You can blame apache or windows kernel but the point is the 
error started with an PHP script.. Please check this Mike before respond

------------------------------------------------------------------------
[2012-01-17 19:19:00] m...@php.net

Thank you for taking the time to write to us, but this is not
a bug. Please double-check the documentation available at
http://www.php.net/manual/ and the instructions on how to report
a bug at http://bugs.php.net/how-to-report.php



------------------------------------------------------------------------
[2012-01-10 16:43:25] valentiny510 at yahoo dot es

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;
}

------------------------------------------------------------------------
[2012-01-10 15:25:37] phpmpan at mpan dot pl

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 ------------

------------------------------------------------------------------------
[2012-01-09 06:16:37] 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)


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



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

Reply via email to