Browse Source

Fixed bug #42802 (Namespace not supported in typehints)

experimental/phar_tar
Dmitry Stogov 18 years ago
parent
commit
8d8d86eb7a
  1. 45
      Zend/tests/bug42802.phpt
  2. 3
      Zend/zend_compile.c
  3. 12
      Zend/zend_execute.c
  4. 6
      Zend/zend_language_parser.y
  5. 10
      Zend/zend_vm_def.h
  6. 10
      Zend/zend_vm_execute.h

45
Zend/tests/bug42802.phpt

@ -0,0 +1,45 @@
--TEST--
Bug #42802 (Namespace not supported in typehints)
--FILE--
<?php
namespace foo;
class bar {
}
function test1(bar $bar) {
echo "ok\n";
}
function test2(foo::bar $bar) {
echo "ok\n";
}
function test3(::foo::bar $bar) {
echo "ok\n";
}
function test4(::Exception $e) {
echo "ok\n";
}
function test5(Exception $e) {
echo "ok\n";
}
function test6(::bar $bar) {
echo "bug\n";
}
$x = new bar();
$y = new Exception();
test1($x);
test2($x);
test3($x);
test4($y);
test5($y);
test6($x);
--EXPECTF--
ok
ok
ok
ok
ok
Catchable fatal error: Argument 1 passed to foo::test6() must be an instance of bar, instance of foo::bar given, called in %sbug42802.php on line 23

3
Zend/zend_compile.c

@ -29,6 +29,8 @@
ZEND_API zend_op_array *(*zend_compile_file)(zend_file_handle *file_handle, int type TSRMLS_DC);
ZEND_API zend_op_array *(*zend_compile_string)(zval *source_string, char *filename TSRMLS_DC);
void zend_resolve_class_name(znode *class_name, ulong *fetch_type, int check_ns_name TSRMLS_DC);
#ifndef ZTS
ZEND_API zend_compiler_globals compiler_globals;
ZEND_API zend_executor_globals executor_globals;
@ -1412,6 +1414,7 @@ void zend_do_receive_arg(zend_uchar op, znode *var, znode *offset, znode *initia
if (class_type->op_type != IS_UNUSED) {
cur_arg_info->allow_null = 0;
if (Z_TYPE(class_type->u.constant) == IS_STRING || Z_TYPE(class_type->u.constant) == IS_UNICODE) {
zend_resolve_class_name(class_type, &opline->extended_value, 1 TSRMLS_CC);
cur_arg_info->class_name = Z_UNIVAL(class_type->u.constant);
cur_arg_info->class_name_len = Z_UNILEN(class_type->u.constant);
if (op == ZEND_RECV_INIT) {

12
Zend/zend_execute.c

@ -497,9 +497,9 @@ static inline void make_real_object(zval **object_ptr TSRMLS_DC) /* {{{ */
}
/* }}} */
static inline char * zend_verify_arg_class_kind(zend_arg_info *cur_arg_info, zstr *class_name, zend_class_entry **pce TSRMLS_DC) /* {{{ */
static inline char * zend_verify_arg_class_kind(zend_arg_info *cur_arg_info, ulong fetch_type, zstr *class_name, zend_class_entry **pce TSRMLS_DC) /* {{{ */
{
*pce = 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 | ZEND_FETCH_CLASS_NO_AUTOLOAD) TSRMLS_CC);
*pce = zend_u_fetch_class(UG(unicode) ? IS_UNICODE : IS_STRING, cur_arg_info->class_name, cur_arg_info->class_name_len, (fetch_type | ZEND_FETCH_CLASS_AUTO | ZEND_FETCH_CLASS_NO_AUTOLOAD) TSRMLS_CC);
*class_name = (*pce) ? (*pce)->name: cur_arg_info->class_name;
if (*pce && (*pce)->ce_flags & ZEND_ACC_INTERFACE) {
@ -534,7 +534,7 @@ static inline int zend_verify_arg_error(zend_function *zf, zend_uint arg_num, ze
}
/* }}} */
static inline int 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, ulong fetch_type TSRMLS_DC) /* {{{ */
{
zend_arg_info *cur_arg_info;
char *need_msg;
@ -550,16 +550,16 @@ static inline int zend_verify_arg_type(zend_function *zf, zend_uint arg_num, zva
zstr class_name;
if (!arg) {
need_msg = zend_verify_arg_class_kind(cur_arg_info, &class_name, &ce TSRMLS_CC);
need_msg = zend_verify_arg_class_kind(cur_arg_info, fetch_type, &class_name, &ce TSRMLS_CC);
return zend_verify_arg_error(zf, arg_num, cur_arg_info, need_msg, class_name, "none", EMPTY_ZSTR TSRMLS_CC);
}
if (Z_TYPE_P(arg) == IS_OBJECT) {
need_msg = zend_verify_arg_class_kind(cur_arg_info, &class_name, &ce TSRMLS_CC);
need_msg = zend_verify_arg_class_kind(cur_arg_info, fetch_type, &class_name, &ce TSRMLS_CC);
if (!ce || !instanceof_function(Z_OBJCE_P(arg), ce TSRMLS_CC)) {
return zend_verify_arg_error(zf, arg_num, cur_arg_info, need_msg, class_name, "instance of ", Z_OBJCE_P(arg)->name TSRMLS_CC);
}
} else if (Z_TYPE_P(arg) != IS_NULL || !cur_arg_info->allow_null) {
need_msg = zend_verify_arg_class_kind(cur_arg_info, &class_name, &ce TSRMLS_CC);
need_msg = zend_verify_arg_class_kind(cur_arg_info, fetch_type, &class_name, &ce TSRMLS_CC);
return zend_verify_arg_error(zf, arg_num, cur_arg_info, need_msg, class_name, zend_zval_type_name(arg), EMPTY_ZSTR TSRMLS_CC);
}
} else if (cur_arg_info->array_type_hint) {

6
Zend/zend_language_parser.y

@ -455,9 +455,9 @@ non_empty_parameter_list:
optional_class_type:
/* empty */ { $$.op_type = IS_UNUSED; }
| T_STRING { $$ = $1; }
| T_ARRAY { $$.op_type = IS_CONST; Z_TYPE($$.u.constant)=IS_NULL;}
/* empty */ { $$.op_type = IS_UNUSED; }
| fully_qualified_class_name { $$ = $1; }
| T_ARRAY { $$.op_type = IS_CONST; Z_TYPE($$.u.constant)=IS_NULL;}
;

10
Zend/zend_vm_def.h

@ -2025,7 +2025,7 @@ ZEND_VM_HELPER(zend_do_fcall_common_helper, ANY, ANY)
arg_count = (ulong)(zend_uintptr_t) *p;
while (arg_count>0) {
zend_verify_arg_type(EX(function_state).function, ++i, *(p-arg_count) TSRMLS_CC);
zend_verify_arg_type(EX(function_state).function, ++i, *(p-arg_count), 0 TSRMLS_CC);
arg_count--;
}
}
@ -2440,7 +2440,7 @@ 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);
if (zend_verify_arg_type((zend_function *) EG(active_op_array), arg_num, NULL TSRMLS_CC)) {
if (zend_verify_arg_type((zend_function *) EG(active_op_array), arg_num, NULL, opline->extended_value 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 {
@ -2454,7 +2454,7 @@ ZEND_VM_HANDLER(63, ZEND_RECV, ANY, ANY)
zend_free_op free_res;
zval **var_ptr;
zend_verify_arg_type((zend_function *) EG(active_op_array), arg_num, *param TSRMLS_CC);
zend_verify_arg_type((zend_function *) EG(active_op_array), arg_num, *param, opline->extended_value TSRMLS_CC);
var_ptr = get_zval_ptr_ptr(&opline->result, EX(Ts), &free_res, BP_VAR_W);
if (PZVAL_IS_REF(*param)) {
zend_assign_to_variable_reference(var_ptr, param TSRMLS_CC);
@ -2492,13 +2492,13 @@ ZEND_VM_HANDLER(64, ZEND_RECV_INIT, ANY, CONST)
param = NULL;
assignment_value = &opline->op2.u.constant;
}
zend_verify_arg_type((zend_function *) EG(active_op_array), arg_num, assignment_value TSRMLS_CC);
zend_verify_arg_type((zend_function *) EG(active_op_array), arg_num, assignment_value, opline->extended_value TSRMLS_CC);
zend_assign_to_variable(NULL, &opline->result, NULL, assignment_value, IS_VAR, EX(Ts) TSRMLS_CC);
} else {
zval **var_ptr = get_zval_ptr_ptr(&opline->result, EX(Ts), &free_res, BP_VAR_W);
assignment_value = *param;
zend_verify_arg_type((zend_function *) EG(active_op_array), arg_num, assignment_value TSRMLS_CC);
zend_verify_arg_type((zend_function *) EG(active_op_array), arg_num, assignment_value, opline->extended_value TSRMLS_CC);
if (PZVAL_IS_REF(assignment_value)) {
zend_assign_to_variable_reference(var_ptr, param TSRMLS_CC);
} else {

10
Zend/zend_vm_execute.h

@ -192,7 +192,7 @@ static int zend_do_fcall_common_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS)
arg_count = (ulong)(zend_uintptr_t) *p;
while (arg_count>0) {
zend_verify_arg_type(EX(function_state).function, ++i, *(p-arg_count) TSRMLS_CC);
zend_verify_arg_type(EX(function_state).function, ++i, *(p-arg_count), 0 TSRMLS_CC);
arg_count--;
}
}
@ -366,7 +366,7 @@ 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);
if (zend_verify_arg_type((zend_function *) EG(active_op_array), arg_num, NULL TSRMLS_CC)) {
if (zend_verify_arg_type((zend_function *) EG(active_op_array), arg_num, NULL, opline->extended_value 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 {
@ -380,7 +380,7 @@ static int ZEND_RECV_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
zend_free_op free_res;
zval **var_ptr;
zend_verify_arg_type((zend_function *) EG(active_op_array), arg_num, *param TSRMLS_CC);
zend_verify_arg_type((zend_function *) EG(active_op_array), arg_num, *param, opline->extended_value TSRMLS_CC);
var_ptr = get_zval_ptr_ptr(&opline->result, EX(Ts), &free_res, BP_VAR_W);
if (PZVAL_IS_REF(*param)) {
zend_assign_to_variable_reference(var_ptr, param TSRMLS_CC);
@ -772,13 +772,13 @@ static int ZEND_RECV_INIT_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
param = NULL;
assignment_value = &opline->op2.u.constant;
}
zend_verify_arg_type((zend_function *) EG(active_op_array), arg_num, assignment_value TSRMLS_CC);
zend_verify_arg_type((zend_function *) EG(active_op_array), arg_num, assignment_value, opline->extended_value TSRMLS_CC);
zend_assign_to_variable(NULL, &opline->result, NULL, assignment_value, IS_VAR, EX(Ts) TSRMLS_CC);
} else {
zval **var_ptr = get_zval_ptr_ptr(&opline->result, EX(Ts), &free_res, BP_VAR_W);
assignment_value = *param;
zend_verify_arg_type((zend_function *) EG(active_op_array), arg_num, assignment_value TSRMLS_CC);
zend_verify_arg_type((zend_function *) EG(active_op_array), arg_num, assignment_value, opline->extended_value TSRMLS_CC);
if (PZVAL_IS_REF(assignment_value)) {
zend_assign_to_variable_reference(var_ptr, param TSRMLS_CC);
} else {

Loading…
Cancel
Save