]> granicus.if.org Git - php/commitdiff
Fixed bug #37251 (deadlock when custom error handler is to catch array type hint...
authorDmitry Stogov <dmitry@php.net>
Fri, 5 May 2006 08:04:55 +0000 (08:04 +0000)
committerDmitry Stogov <dmitry@php.net>
Fri, 5 May 2006 08:04:55 +0000 (08:04 +0000)
Zend/tests/bug37251.phpt [new file with mode: 0644]
Zend/zend_execute.c
Zend/zend_vm_def.h
Zend/zend_vm_execute.h

diff --git a/Zend/tests/bug37251.phpt b/Zend/tests/bug37251.phpt
new file mode 100644 (file)
index 0000000..320d544
--- /dev/null
@@ -0,0 +1,19 @@
+--TEST--
+Bug #37251 (deadlock when custom error handler is to catch array type hint error) 
+--FILE--
+<?php
+function error_handler($errno, $errstr, $errfile, $errline, $context) {
+       echo 'OK';
+}
+
+set_error_handler('error_handler');
+
+class Foo {    
+       function bar(array $foo) {
+       }
+}
+
+$foo = new Foo();
+$foo->bar();
+--EXPECT--
+OK
index 2f7ab9553cde53e48a5d21c8a6011331b577c667..0173573b23eeb3e6d9dbf6235d4b8bcb96e36c10 100644 (file)
@@ -470,7 +470,7 @@ static inline void make_real_object(zval **object_ptr TSRMLS_DC)
        }
 }
 
-static inline void zend_verify_arg_type(zend_function *zf, zend_uint arg_num, zval *arg TSRMLS_DC)
+static inline int zend_verify_arg_type(zend_function *zf, zend_uint arg_num, zval *arg TSRMLS_DC)
 {
        zend_arg_info *cur_arg_info;
        zend_execute_data *ptr = EG(current_execute_data)->prev_execute_data;
@@ -479,7 +479,7 @@ static inline void zend_verify_arg_type(zend_function *zf, zend_uint arg_num, zv
 
        if (!zf->common.arg_info
                || arg_num>zf->common.num_args) {
-               return;
+               return 1;
        }
 
        cur_arg_info = &zf->common.arg_info[arg_num-1];
@@ -494,6 +494,7 @@ static inline void zend_verify_arg_type(zend_function *zf, zend_uint arg_num, zv
                        } else {
                                zend_error(E_RECOVERABLE_ERROR, "Argument %d passed to %v%s%v() must be an object of class %v", arg_num, fclass, fsep, fname, cur_arg_info->class_name);
                        }
+                       return 0;
                }
                switch (Z_TYPE_P(arg)) {
                        case IS_NULL:
@@ -503,14 +504,14 @@ static inline void zend_verify_arg_type(zend_function *zf, zend_uint arg_num, zv
                                        } else {
                                                zend_error(E_RECOVERABLE_ERROR, "Argument %d passed to %v%s%v() must not be null", arg_num, fclass, fsep, fname);
                                        }
+                                       return 0;
                                }
                                break;
                        case IS_OBJECT: {
                                        zend_class_entry *ce = zend_u_fetch_class(UG(unicode) ? IS_UNICODE : IS_STRING, cur_arg_info->class_name, cur_arg_info->class_name_len, ZEND_FETCH_CLASS_AUTO TSRMLS_CC);
                                        if (!instanceof_function(Z_OBJCE_P(arg), ce TSRMLS_CC)) {
                                                char *error_msg;
-
-                                               if (ce->ce_flags & ZEND_ACC_INTERFACE) {
+                                                       if (ce->ce_flags & ZEND_ACC_INTERFACE) {
                                                        error_msg = "implement interface";
                                                } else {
                                                        error_msg = "be an instance of";
@@ -520,6 +521,7 @@ static inline void zend_verify_arg_type(zend_function *zf, zend_uint arg_num, zv
                                                } else {
                                                        zend_error(E_RECOVERABLE_ERROR, "Argument %d passed to %v%s%v() must %s %v", arg_num, fclass, fsep, fname, error_msg, ce->name);
                                                }
+                                               return 0;
                                        }
                                }
                                break;
@@ -529,15 +531,16 @@ static inline void zend_verify_arg_type(zend_function *zf, zend_uint arg_num, zv
                                } else {
                                        zend_error(E_RECOVERABLE_ERROR, "Argument %d passed to %v%s%v() must be an object of class %v", arg_num, fclass, fsep, fname, cur_arg_info->class_name);
                                }
-                               break;
+                               return 0;
                }
-       }       else if (cur_arg_info->array_type_hint) {
+       } else if (cur_arg_info->array_type_hint) {
                if (!arg) {
                        if (ptr && ptr->op_array) {
                                zend_error(E_RECOVERABLE_ERROR, "Argument %d passed to %v%s%v() must be an array, called in %s on line %d and defined", arg_num, fclass, fsep, fname, ptr->op_array->filename, ptr->opline->lineno);
                        } else {
                                zend_error(E_RECOVERABLE_ERROR, "Argument %d passed to %v%s%v() must be an array", arg_num, fclass, fsep, fname);
                        }
+                       return 0;
                }
                switch (Z_TYPE_P(arg)) {
                        case IS_NULL:
@@ -547,6 +550,7 @@ static inline void zend_verify_arg_type(zend_function *zf, zend_uint arg_num, zv
                                        } else {
                                                zend_error(E_RECOVERABLE_ERROR, "Argument %d passed to %v%s%v() must not be null", arg_num, fclass, fsep, fname);
                                        }
+                                       return 0;
                                }
                                break;
                        case IS_ARRAY:
@@ -557,9 +561,10 @@ static inline void zend_verify_arg_type(zend_function *zf, zend_uint arg_num, zv
                                } else {
                                        zend_error(E_RECOVERABLE_ERROR, "Argument %d passed to %v%s%v() must be an array", arg_num, fclass, fsep, fname);
                                }
-                               break;
+                               return 0;
                }
        }
+       return 1;
 }
 
 
index 808c0cb9d0bc725fcf2a52ed3a93541e604ef8b2..0f19daffedc6726656dd2084b32b88eb413d2668 100644 (file)
@@ -2286,11 +2286,12 @@ ZEND_VM_HANDLER(63, ZEND_RECV, ANY, ANY)
                zstr class_name = get_active_class_name(&space TSRMLS_CC);
                zend_execute_data *ptr = EX(prev_execute_data);
 
-               zend_verify_arg_type((zend_function *) EG(active_op_array), arg_num, NULL TSRMLS_CC);
-               if(ptr && ptr->op_array) {
-                       zend_error(E_WARNING, "Missing argument %ld for %v%s%v(), called in %s on line %d and defined", Z_LVAL(opline->op1.u.constant), class_name, space, get_active_function_name(TSRMLS_C), ptr->op_array->filename, ptr->opline->lineno);
-               } else {
-                       zend_error(E_WARNING, "Missing argument %ld for %v%s%v()", Z_LVAL(opline->op1.u.constant), class_name, space, get_active_function_name(TSRMLS_C));
+               if (zend_verify_arg_type((zend_function *) EG(active_op_array), arg_num, NULL TSRMLS_CC)) {
+                       if(ptr && ptr->op_array) {
+                               zend_error(E_WARNING, "Missing argument %ld for %v%s%v(), called in %s on line %d and defined", Z_LVAL(opline->op1.u.constant), class_name, space, get_active_function_name(TSRMLS_C), ptr->op_array->filename, ptr->opline->lineno);
+                       } else {
+                               zend_error(E_WARNING, "Missing argument %ld for %v%s%v()", Z_LVAL(opline->op1.u.constant), class_name, space, get_active_function_name(TSRMLS_C));
+                       }
                }
                if (opline->result.op_type == IS_VAR) {
                        PZVAL_UNLOCK_FREE(*EX_T(opline->result.u.var).var.ptr_ptr);
index a08f576afe8de023579b39a95d4c71a4066f87f4..201c8e50752099b9768abd4004cda7a79f2cde2d 100644 (file)
@@ -370,11 +370,12 @@ static int ZEND_RECV_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                zstr class_name = get_active_class_name(&space TSRMLS_CC);
                zend_execute_data *ptr = EX(prev_execute_data);
 
-               zend_verify_arg_type((zend_function *) EG(active_op_array), arg_num, NULL TSRMLS_CC);
-               if(ptr && ptr->op_array) {
-                       zend_error(E_WARNING, "Missing argument %ld for %v%s%v(), called in %s on line %d and defined", Z_LVAL(opline->op1.u.constant), class_name, space, get_active_function_name(TSRMLS_C), ptr->op_array->filename, ptr->opline->lineno);
-               } else {
-                       zend_error(E_WARNING, "Missing argument %ld for %v%s%v()", Z_LVAL(opline->op1.u.constant), class_name, space, get_active_function_name(TSRMLS_C));
+               if (zend_verify_arg_type((zend_function *) EG(active_op_array), arg_num, NULL TSRMLS_CC)) {
+                       if(ptr && ptr->op_array) {
+                               zend_error(E_WARNING, "Missing argument %ld for %v%s%v(), called in %s on line %d and defined", Z_LVAL(opline->op1.u.constant), class_name, space, get_active_function_name(TSRMLS_C), ptr->op_array->filename, ptr->opline->lineno);
+                       } else {
+                               zend_error(E_WARNING, "Missing argument %ld for %v%s%v()", Z_LVAL(opline->op1.u.constant), class_name, space, get_active_function_name(TSRMLS_C));
+                       }
                }
                if (opline->result.op_type == IS_VAR) {
                        PZVAL_UNLOCK_FREE(*EX_T(opline->result.u.var).var.ptr_ptr);