From: Nikita Popov Date: Tue, 9 Jun 2020 14:30:46 +0000 (+0200) Subject: Back up fake_scope in zend_call_function X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=e56e53a59dc1257210939f99975b6617a77e63e4;p=php Back up fake_scope in zend_call_function We regularly find new places where we forgot to reset fake_scope. Instead of having to handle this for each caller of zend_call_function() and similar APIs, handle it directly in zend_call_function(). --- diff --git a/Zend/zend.c b/Zend/zend.c index fd53532537..b72184e726 100644 --- a/Zend/zend.c +++ b/Zend/zend.c @@ -1271,7 +1271,6 @@ static ZEND_COLD void zend_error_impl( zend_class_entry *saved_class_entry; zend_stack loop_var_stack; zend_stack delayed_oplines_stack; - zend_class_entry *orig_fake_scope; int type = orig_type & E_ALL; /* Report about uncaught exception in case of fatal errors */ @@ -1357,9 +1356,6 @@ static ZEND_COLD void zend_error_impl( CG(in_compilation) = 0; } - orig_fake_scope = EG(fake_scope); - EG(fake_scope) = NULL; - if (call_user_function(CG(function_table), NULL, &orig_user_error_handler, &retval, 4, params) == SUCCESS) { if (Z_TYPE(retval) != IS_UNDEF) { if (Z_TYPE(retval) == IS_FALSE) { @@ -1372,8 +1368,6 @@ static ZEND_COLD void zend_error_impl( zend_error_cb(orig_type, error_filename, error_lineno, message); } - EG(fake_scope) = orig_fake_scope; - if (in_compilation) { CG(active_class_entry) = saved_class_entry; RESTORE_STACK(loop_var_stack); diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index c5626a0df3..b650444d1c 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -646,6 +646,7 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache) / zend_function *func; uint32_t call_info; void *object_or_called_scope; + zend_class_entry *orig_fake_scope; ZVAL_UNDEF(fci->retval); @@ -791,6 +792,8 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache) / ZEND_ADD_CALL_FLAG(call, call_info); } + orig_fake_scope = EG(fake_scope); + EG(fake_scope) = NULL; if (func->type == ZEND_USER_FUNCTION) { int call_via_handler = (func->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE) != 0; const zend_op *current_opline_before_exception = EG(opline_before_exception); @@ -841,6 +844,7 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache) / } } } + EG(fake_scope) = orig_fake_scope; zend_vm_stack_free_call_frame(call); @@ -914,7 +918,6 @@ ZEND_API zend_class_entry *zend_lookup_class_ex(zend_string *name, zend_string * zend_string *lc_name; zend_fcall_info fcall_info; zend_fcall_info_cache fcall_cache; - zend_class_entry *orig_fake_scope; if (key) { lc_name = key; @@ -1005,14 +1008,11 @@ ZEND_API zend_class_entry *zend_lookup_class_ex(zend_string *name, zend_string * fcall_cache.called_scope = NULL; fcall_cache.object = NULL; - orig_fake_scope = EG(fake_scope); - EG(fake_scope) = NULL; zend_exception_save(); if ((zend_call_function(&fcall_info, &fcall_cache) == SUCCESS) && !EG(exception)) { ce = zend_hash_find_ptr(EG(class_table), lc_name); } zend_exception_restore(); - EG(fake_scope) = orig_fake_scope; zval_ptr_dtor(&args[0]); zval_ptr_dtor_str(&fcall_info.function_name); diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c index 05944bbbdf..e8d391ed04 100644 --- a/Zend/zend_object_handlers.c +++ b/Zend/zend_object_handlers.c @@ -177,58 +177,34 @@ ZEND_API HashTable *zend_std_get_debug_info(zend_object *object, int *is_temp) / static void zend_std_call_getter(zend_object *zobj, zend_string *prop_name, zval *retval) /* {{{ */ { - zend_class_entry *orig_fake_scope = EG(fake_scope); zval member; - - EG(fake_scope) = NULL; - ZVAL_STR(&member, prop_name); zend_call_known_instance_method_with_1_params(zobj->ce->__get, zobj, retval, &member); - - EG(fake_scope) = orig_fake_scope; } /* }}} */ static void zend_std_call_setter(zend_object *zobj, zend_string *prop_name, zval *value) /* {{{ */ { - zend_class_entry *orig_fake_scope = EG(fake_scope); zval args[2]; - - EG(fake_scope) = NULL; - ZVAL_STR(&args[0], prop_name); ZVAL_COPY_VALUE(&args[1], value); zend_call_known_instance_method(zobj->ce->__set, zobj, NULL, 2, args); - - EG(fake_scope) = orig_fake_scope; } /* }}} */ static void zend_std_call_unsetter(zend_object *zobj, zend_string *prop_name) /* {{{ */ { - zend_class_entry *orig_fake_scope = EG(fake_scope); zval member; - - EG(fake_scope) = NULL; - ZVAL_STR(&member, prop_name); zend_call_known_instance_method_with_1_params(zobj->ce->__unset, zobj, NULL, &member); - - EG(fake_scope) = orig_fake_scope; } /* }}} */ static void zend_std_call_issetter(zend_object *zobj, zend_string *prop_name, zval *retval) /* {{{ */ { - zend_class_entry *orig_fake_scope = EG(fake_scope); zval member; - - EG(fake_scope) = NULL; - ZVAL_STR(&member, prop_name); zend_call_known_instance_method_with_1_params(zobj->ce->__isset, zobj, retval, &member); - - EG(fake_scope) = orig_fake_scope; } /* }}} */ @@ -1711,12 +1687,9 @@ ZEND_API int zend_std_cast_object_tostring(zend_object *readobj, zval *writeobj, zend_class_entry *ce = readobj->ce; if (ce->__tostring) { zval retval; - zend_class_entry *fake_scope = EG(fake_scope); - EG(fake_scope) = NULL; GC_ADDREF(readobj); zend_call_known_instance_method_with_0_params(ce->__tostring, readobj, &retval); zend_object_release(readobj); - EG(fake_scope) = fake_scope; if (EXPECTED(Z_TYPE(retval) == IS_STRING)) { ZVAL_COPY_VALUE(writeobj, &retval); return SUCCESS; diff --git a/Zend/zend_objects.c b/Zend/zend_objects.c index f25983ece3..0e873f0681 100644 --- a/Zend/zend_objects.c +++ b/Zend/zend_objects.c @@ -97,7 +97,6 @@ ZEND_API void zend_objects_destroy_object(zend_object *object) if (destructor) { zend_object *old_exception; - zend_class_entry *orig_fake_scope; if (destructor->op_array.fn_flags & (ZEND_ACC_PRIVATE|ZEND_ACC_PROTECTED)) { if (destructor->op_array.fn_flags & ZEND_ACC_PRIVATE) { @@ -156,8 +155,6 @@ ZEND_API void zend_objects_destroy_object(zend_object *object) EG(exception) = NULL; } } - orig_fake_scope = EG(fake_scope); - EG(fake_scope) = NULL; zend_call_known_instance_method_with_0_params(destructor, object, NULL); @@ -169,7 +166,6 @@ ZEND_API void zend_objects_destroy_object(zend_object *object) } } OBJ_RELEASE(object); - EG(fake_scope) = orig_fake_scope; } }