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().
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 */
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) {
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);
zend_function *func;
uint32_t call_info;
void *object_or_called_scope;
+ zend_class_entry *orig_fake_scope;
ZVAL_UNDEF(fci->retval);
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);
}
}
}
+ EG(fake_scope) = orig_fake_scope;
zend_vm_stack_free_call_frame(call);
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;
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);
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;
}
/* }}} */
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;
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) {
EG(exception) = NULL;
}
}
- orig_fake_scope = EG(fake_scope);
- EG(fake_scope) = NULL;
zend_call_known_instance_method_with_0_params(destructor, object, NULL);
}
}
OBJ_RELEASE(object);
- EG(fake_scope) = orig_fake_scope;
}
}