]> granicus.if.org Git - php/commitdiff
- Improve ARG_INFO() macros to support supplying required_num_args
authorZeev Suraski <zeev@php.net>
Wed, 25 Feb 2004 14:56:45 +0000 (14:56 +0000)
committerZeev Suraski <zeev@php.net>
Wed, 25 Feb 2004 14:56:45 +0000 (14:56 +0000)
- Initial fix for foreach($o->mthd()->arr) crash (now leaks)

Zend/zend_API.c
Zend/zend_API.h
Zend/zend_compile.c
Zend/zend_compile.h
Zend/zend_execute.c

index 90c12fa8267cd6a0b07f1c51ab7ad0ce082f38b1..ea5534ac5141cc20a9e8b46a0657648d97a1a6ec 100644 (file)
@@ -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 {
index 19b5c96dd067ed6eec215a0bba398bdd092d9ca6..d3b0c76f2b78dcb81f2b4109856b343df00ef9b9 100644 (file)
@@ -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 */
index 7407429223eed5c15e9d9706565202f7d4f92959..559d1775818400d2f6647b1310be1e805fb022e7 100644 (file)
@@ -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;
        }
index bb271d9dc289991993c55c7c939c2de3fba6422c..472209034aef88ad4742a062bbe70e23214be890 100644 (file)
@@ -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 {
index b45a7a1cf335490de31308b69bdfea4db4679d51..d6f263b1d20654123ec134d5a276a3464b2f6edb 100644 (file)
@@ -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();
 }