diff options
Diffstat (limited to 'Zend/zend_builtin_functions.c')
| -rw-r--r-- | Zend/zend_builtin_functions.c | 125 |
1 files changed, 99 insertions, 26 deletions
diff --git a/Zend/zend_builtin_functions.c b/Zend/zend_builtin_functions.c index a576455fa3..e5f77d8960 100644 --- a/Zend/zend_builtin_functions.c +++ b/Zend/zend_builtin_functions.c @@ -31,6 +31,12 @@ #undef ZEND_TEST_EXCEPTIONS +#if ZEND_DEBUG +static zend_class_entry *zend_test_interface; +static zend_class_entry *zend_test_class; +static zend_object_handlers zend_test_class_handlers; +#endif + static ZEND_FUNCTION(zend_version); static ZEND_FUNCTION(func_num_args); static ZEND_FUNCTION(func_get_arg); @@ -257,6 +263,51 @@ ZEND_END_ARG_INFO() /* }}} */ +#if ZEND_DEBUG +static zend_object *zend_test_class_new(zend_class_entry *class_type) /* {{{ */ { + zend_object *obj = zend_objects_new(class_type); + obj->handlers = &zend_test_class_handlers; + return obj; +} +/* }}} */ + +static zend_function *zend_test_class_method_get(zend_object **object, zend_string *name, const zval *key) /* {{{ */ { + zend_internal_function *fptr = emalloc(sizeof(zend_internal_function)); + fptr->type = ZEND_OVERLOADED_FUNCTION_TEMPORARY; + fptr->num_args = 1; + fptr->arg_info = NULL; + fptr->scope = (*object)->ce; + fptr->fn_flags = ZEND_ACC_CALL_VIA_HANDLER; + fptr->function_name = zend_string_copy(name); + fptr->handler = ZEND_FN(zend_test_func); + zend_set_function_arg_flags((zend_function*)fptr); + + return (zend_function*)fptr; +} +/* }}} */ + +static zend_function *zend_test_class_static_method_get(zend_class_entry *ce, zend_string *name) /* {{{ */ { + zend_internal_function *fptr = emalloc(sizeof(zend_internal_function)); + fptr->type = ZEND_OVERLOADED_FUNCTION; + fptr->num_args = 1; + fptr->arg_info = NULL; + fptr->scope = ce; + fptr->fn_flags = ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_STATIC; + fptr->function_name = name; + fptr->handler = ZEND_FN(zend_test_func); + zend_set_function_arg_flags((zend_function*)fptr); + + return (zend_function*)fptr; +} +/* }}} */ + +static int zend_test_class_call_method(zend_string *method, zend_object *object, INTERNAL_FUNCTION_PARAMETERS) /* {{{ */ { + RETVAL_STR(zend_string_copy(method)); + return 0; +} +/* }}} */ +#endif + static const zend_function_entry builtin_functions[] = { /* {{{ */ ZEND_FE(zend_version, arginfo_zend__void) ZEND_FE(func_num_args, arginfo_zend__void) @@ -339,6 +390,21 @@ ZEND_MINIT_FUNCTION(core) { /* {{{ */ zend_register_default_classes(); +#if ZEND_DEBUG + INIT_CLASS_ENTRY(class_entry, "_ZendTestInterface", NULL); + zend_test_interface = zend_register_internal_interface(&class_entry); + zend_declare_class_constant_long(zend_test_interface, ZEND_STRL("DUMMY"), 0); + INIT_CLASS_ENTRY(class_entry, "_ZendTestClass", NULL); + zend_test_class = zend_register_internal_class_ex(&class_entry, NULL); + zend_class_implements(zend_test_class, 1, zend_test_interface); + zend_test_class->create_object = zend_test_class_new; + zend_test_class->get_static_method = zend_test_class_static_method_get; + + memcpy(&zend_test_class_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); + zend_test_class_handlers.get_method = zend_test_class_method_get; + zend_test_class_handlers.call_method = zend_test_class_call_method; +#endif + return SUCCESS; } /* }}} */ @@ -460,13 +526,13 @@ ZEND_FUNCTION(func_get_arg) arg_count = ZEND_CALL_NUM_ARGS(ex); - if (requested_offset >= arg_count) { + if ((zend_ulong)requested_offset >= arg_count) { zend_error(E_WARNING, "func_get_arg(): Argument " ZEND_LONG_FMT " not passed to function", requested_offset); RETURN_FALSE; } first_extra_arg = ex->func->op_array.num_args; - if (requested_offset >= first_extra_arg && (ZEND_CALL_NUM_ARGS(ex) > first_extra_arg)) { + if ((zend_ulong)requested_offset >= first_extra_arg && (ZEND_CALL_NUM_ARGS(ex) > first_extra_arg)) { arg = ZEND_CALL_VAR_NUM(ex, ex->func->op_array.last_var + ex->func->op_array.T) + (requested_offset - first_extra_arg); } else { arg = ZEND_CALL_ARG(ex, requested_offset + 1); @@ -689,7 +755,7 @@ ZEND_FUNCTION(each) Return the current error_reporting level, and if an argument was passed - change to the new level */ ZEND_FUNCTION(error_reporting) { - zval *err; + zval *err = NULL; int old_error_reporting; #ifndef FAST_ZPP @@ -916,7 +982,7 @@ ZEND_FUNCTION(defined) ZEND_PARSE_PARAMETERS_END(); #endif - if (zend_get_constant_ex(name, NULL, ZEND_FETCH_CLASS_SILENT)) { + if (zend_get_constant_ex(name, zend_get_executed_scope(), ZEND_FETCH_CLASS_SILENT)) { RETURN_TRUE; } else { RETURN_FALSE; @@ -935,8 +1001,10 @@ ZEND_FUNCTION(get_class) } if (!obj) { - if (EG(scope)) { - RETURN_STR_COPY(EG(scope)->name); + zend_class_entry *scope = zend_get_executed_scope(); + + if (scope) { + RETURN_STR_COPY(scope->name); } else { zend_error(E_WARNING, "get_class() called without object from outside a class"); RETURN_FALSE; @@ -960,8 +1028,11 @@ ZEND_FUNCTION(get_called_class) called_scope = zend_get_called_scope(execute_data); if (called_scope) { RETURN_STR_COPY(called_scope->name); - } else if (!EG(scope)) { - zend_error(E_WARNING, "get_called_class() called from outside a class"); + } else { + zend_class_entry *scope = zend_get_executed_scope(); + if (!scope) { + zend_error(E_WARNING, "get_called_class() called from outside a class"); + } } RETURN_FALSE; } @@ -979,7 +1050,7 @@ ZEND_FUNCTION(get_parent_class) } if (!ZEND_NUM_ARGS()) { - ce = EG(scope); + ce = zend_get_executed_scope(); if (ce && ce->parent) { RETURN_STR_COPY(ce->parent->name); } else { @@ -1076,7 +1147,7 @@ ZEND_FUNCTION(is_a) /* }}} */ /* {{{ add_class_vars */ -static void add_class_vars(zend_class_entry *ce, int statics, zval *return_value) +static void add_class_vars(zend_class_entry *scope, zend_class_entry *ce, int statics, zval *return_value) { zend_property_info *prop_info; zval *prop, prop_copy; @@ -1084,12 +1155,12 @@ static void add_class_vars(zend_class_entry *ce, int statics, zval *return_value ZEND_HASH_FOREACH_STR_KEY_PTR(&ce->properties_info, key, prop_info) { if (((prop_info->flags & ZEND_ACC_SHADOW) && - prop_info->ce != EG(scope)) || + prop_info->ce != scope) || ((prop_info->flags & ZEND_ACC_PROTECTED) && - !zend_check_protected(prop_info->ce, EG(scope))) || + !zend_check_protected(prop_info->ce, scope)) || ((prop_info->flags & ZEND_ACC_PRIVATE) && - ce != EG(scope) && - prop_info->ce != EG(scope))) { + ce != scope && + prop_info->ce != scope)) { continue; } prop = NULL; @@ -1114,7 +1185,7 @@ static void add_class_vars(zend_class_entry *ce, int statics, zval *return_value /* this is necessary to make it able to work with default array * properties, returned to user */ if (Z_OPT_CONSTANT_P(prop)) { - if (UNEXPECTED(zval_update_constant_ex(prop, 0, NULL) != SUCCESS)) { + if (UNEXPECTED(zval_update_constant_ex(prop, NULL) != SUCCESS)) { return; } } @@ -1129,7 +1200,7 @@ static void add_class_vars(zend_class_entry *ce, int statics, zval *return_value ZEND_FUNCTION(get_class_vars) { zend_string *class_name; - zend_class_entry *ce; + zend_class_entry *ce, *scope; if (zend_parse_parameters(ZEND_NUM_ARGS(), "S", &class_name) == FAILURE) { return; @@ -1145,8 +1216,9 @@ ZEND_FUNCTION(get_class_vars) return; } } - add_class_vars(ce, 0, return_value); - add_class_vars(ce, 1, return_value); + scope = zend_get_executed_scope(); + add_class_vars(scope, ce, 0, return_value); + add_class_vars(scope, ce, 1, return_value); } } /* }}} */ @@ -1244,6 +1316,7 @@ ZEND_FUNCTION(get_class_methods) zval *klass; zval method_name; zend_class_entry *ce = NULL; + zend_class_entry *scope; zend_function *mptr; zend_string *key; @@ -1262,15 +1335,16 @@ ZEND_FUNCTION(get_class_methods) } array_init(return_value); + scope = zend_get_executed_scope(); ZEND_HASH_FOREACH_STR_KEY_PTR(&ce->function_table, key, mptr) { if ((mptr->common.fn_flags & ZEND_ACC_PUBLIC) - || (EG(scope) && + || (scope && (((mptr->common.fn_flags & ZEND_ACC_PROTECTED) && - zend_check_protected(mptr->common.scope, EG(scope))) + zend_check_protected(mptr->common.scope, scope)) || ((mptr->common.fn_flags & ZEND_ACC_PRIVATE) && - EG(scope) == mptr->common.scope)))) { + scope == mptr->common.scope)))) { size_t len = ZSTR_LEN(mptr->common.function_name); /* Do not display old-style inherited constructors */ @@ -2036,17 +2110,16 @@ ZEND_FUNCTION(zend_test_func) { zval *arg1, *arg2; - zend_get_parameters(ZEND_NUM_ARGS(), 2, &arg1, &arg2); + zend_parse_parameters(ZEND_NUM_ARGS(), "|zz", &arg1, &arg2); } ZEND_FUNCTION(zend_test_func2) { zval *arg1, *arg2; - zend_get_parameters(ZEND_NUM_ARGS(), 2, &arg1, &arg2); + zend_parse_parameters(ZEND_NUM_ARGS(), "|zz", &arg1, &arg2); } - #ifdef ZTS ZEND_FUNCTION(zend_thread_id) { @@ -2368,7 +2441,7 @@ ZEND_FUNCTION(debug_print_backtrace) } /* $this may be passed into regular internal functions */ - object = Z_OBJ(call->This); + object = (Z_TYPE(call->This) == IS_OBJECT) ? Z_OBJ(call->This) : NULL; if (call->func) { func = call->func; @@ -2587,7 +2660,7 @@ ZEND_API void zend_fetch_debug_backtrace(zval *return_value, int skip_last, int } /* $this may be passed into regular internal functions */ - object = call ? Z_OBJ(call->This) : NULL; + object = (call && (Z_TYPE(call->This) == IS_OBJECT)) ? Z_OBJ(call->This) : NULL; if (call && call->func) { func = call->func; |
