From: Zeev Suraski Date: Wed, 25 Feb 2004 14:56:45 +0000 (+0000) Subject: - Improve ARG_INFO() macros to support supplying required_num_args X-Git-Tag: RELEASE_0_2_0~170 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=7086634a0bcb48d47ad34ca36c188f379d367924;p=php - Improve ARG_INFO() macros to support supplying required_num_args - Initial fix for foreach($o->mthd()->arr) crash (now leaks) --- diff --git a/Zend/zend_API.c b/Zend/zend_API.c index 90c12fa826..ea5534ac51 100644 --- a/Zend/zend_API.c +++ b/Zend/zend_API.c @@ -1221,7 +1221,11 @@ ZEND_API int zend_register_functions(zend_class_entry *scope, zend_function_entr internal_function->arg_info = ptr->arg_info+1; internal_function->num_args = ptr->num_args; /* Currently you cannot denote that the function can accept less arguments than num_args */ - internal_function->required_num_args = ptr->num_args; + if (ptr->arg_info[0].required_num_args == -1) { + internal_function->required_num_args = ptr->num_args; + } else { + internal_function->required_num_args = ptr->arg_info[0].required_num_args; + } internal_function->pass_rest_by_reference = ptr->arg_info[0].pass_by_reference; internal_function->return_reference = ptr->arg_info[0].return_reference; } else { diff --git a/Zend/zend_API.h b/Zend/zend_API.h index 19b5c96dd0..d3b0c76f2b 100644 --- a/Zend/zend_API.h +++ b/Zend/zend_API.h @@ -57,14 +57,14 @@ typedef struct _zend_function_entry { ZEND_FENTRY(name, ZEND_FN(classname##_##alias), arg_info, flags) #define ZEND_ME_MAPPING(name, func_name, arg_types) ZEND_NAMED_FE(name, ZEND_FN(func_name), arg_types) -#define ZEND_ARG_INFO(pass_by_ref, name) { #name, sizeof(#name)-1, NULL, 0, 0, pass_by_ref, 0 }, -#define ZEND_ARG_PASS_INFO(pass_by_ref) { NULL, 0, NULL, 0, 0, pass_by_ref, 0 }, -#define ZEND_ARG_OBJ_INFO(pass_by_ref, name, classname, allow_null) { #name, sizeof(#name)-1, #classname, sizeof(#classname)-1, allow_null, pass_by_ref, 0 }, -#define ZEND_BEGIN_ARG_INFO_EX(name, pass_rest_by_reference, return_reference) \ - zend_arg_info name[] = { \ - { NULL, 0, NULL, 0, 0, pass_rest_by_reference, return_reference }, +#define ZEND_ARG_INFO(pass_by_ref, name) { #name, sizeof(#name)-1, NULL, 0, 0, pass_by_ref, 0, 0 }, +#define ZEND_ARG_PASS_INFO(pass_by_ref) { NULL, 0, NULL, 0, 0, pass_by_ref, 0, 0 }, +#define ZEND_ARG_OBJ_INFO(pass_by_ref, name, classname, allow_null) { #name, sizeof(#name)-1, #classname, sizeof(#classname)-1, allow_null, pass_by_ref, 0, 0 }, +#define ZEND_BEGIN_ARG_INFO_EX(name, pass_rest_by_reference, return_reference, required_num_args) \ + zend_arg_info name[] = { \ + { NULL, 0, NULL, 0, 0, pass_rest_by_reference, return_reference, required_num_args }, #define ZEND_BEGIN_ARG_INFO(name, pass_rest_by_reference) \ - ZEND_BEGIN_ARG_INFO_EX(name, pass_rest_by_reference, ZEND_RETURN_REFERENCE_AGNOSTIC) + ZEND_BEGIN_ARG_INFO_EX(name, pass_rest_by_reference, ZEND_RETURN_REFERENCE_AGNOSTIC, -1) #define ZEND_END_ARG_INFO() }; /* Name macros */ diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 7407429223..559d177581 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -1713,7 +1713,7 @@ static zend_bool zend_do_perform_implementation_check(zend_function *fe) zend_uint i; zend_function *proto = fe->common.prototype; - if (!proto) { + if (!proto || !proto->common.arg_info) { return 1; } @@ -3275,6 +3275,10 @@ void zend_do_foreach_begin(znode *foreach_token, znode *array, znode *open_brack is_variable = 1; } zend_do_end_variable_parse(BP_VAR_W, 0 TSRMLS_CC); + if (CG(active_op_array)->opcodes[CG(active_op_array)->last-1].opcode == ZEND_FETCH_OBJ_W) { + /* FIXME: This will cause a leak, we have to unlock at the end of foreach() */ + CG(active_op_array)->opcodes[CG(active_op_array)->last-1].extended_value |= ZEND_FETCH_ADD_LOCK; + } } else { is_variable = 0; } diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h index bb271d9dc2..472209034a 100644 --- a/Zend/zend_compile.h +++ b/Zend/zend_compile.h @@ -141,6 +141,7 @@ typedef struct _zend_arg_info { zend_bool allow_null; zend_bool pass_by_reference; zend_bool return_reference; + int required_num_args; } zend_arg_info; struct _zend_op_array { diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index b45a7a1cf3..d6f263b1d2 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -2040,6 +2040,9 @@ int zend_fetch_obj_r_handler(ZEND_OPCODE_HANDLER_ARGS) int zend_fetch_obj_w_handler(ZEND_OPCODE_HANDLER_ARGS) { + if (opline->extended_value == ZEND_FETCH_ADD_LOCK) { + PZVAL_LOCK(*EX_T(opline->op1.u.var).var.ptr_ptr); + } zend_fetch_property_address(&opline->result, &opline->op1, &opline->op2, EX(Ts), BP_VAR_W TSRMLS_CC); NEXT_OPCODE(); }