From 52499938142351d20a46c2b941e957ab0d618109 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Fri, 25 Oct 2019 12:47:18 +0200 Subject: [PATCH] Fixed bug #78747 --- NEWS | 1 + ext/opcache/Optimizer/zend_func_info.c | 2 +- .../internal_func_info_static_method.phpt | 14 ++++++++ ext/zend_test/test.c | 36 +++++++++++++------ 4 files changed, 41 insertions(+), 12 deletions(-) create mode 100644 ext/opcache/tests/internal_func_info_static_method.phpt diff --git a/NEWS b/NEWS index f5783273937..ac9a2c27167 100644 --- a/NEWS +++ b/NEWS @@ -19,6 +19,7 @@ PHP NEWS - OpCache: . Fixed bug #78654 (Incorrectly computed opcache checksum on files with non-ascii characters). (mhagstrand) + . Fixed bug #78747 (OpCache corrupts custom extension result). (Nikita) - Reflection: . Fixed bug #78697 (ReflectionClass::ImplementsInterface - inaccurate error diff --git a/ext/opcache/Optimizer/zend_func_info.c b/ext/opcache/Optimizer/zend_func_info.c index 496755d97ca..af9cfa83350 100644 --- a/ext/opcache/Optimizer/zend_func_info.c +++ b/ext/opcache/Optimizer/zend_func_info.c @@ -1215,7 +1215,7 @@ uint32_t zend_get_func_info(const zend_call_info *call_info, const zend_ssa *ssa if (call_info->callee_func->type == ZEND_INTERNAL_FUNCTION) { func_info_t *info; - if ((info = zend_hash_find_ptr(&func_info, Z_STR_P(CRT_CONSTANT_EX(call_info->caller_op_array, call_info->caller_init_opline->op2, ssa->rt_constants)))) != NULL) { + if (!call_info->callee_func->common.scope && (info = zend_hash_find_ptr(&func_info, Z_STR_P(CRT_CONSTANT_EX(call_info->caller_op_array, call_info->caller_init_opline->op2, ssa->rt_constants)))) != NULL) { if (UNEXPECTED(zend_optimizer_is_disabled_func(info->name, info->name_len))) { ret = MAY_BE_NULL; } else if (info->info_func) { diff --git a/ext/opcache/tests/internal_func_info_static_method.phpt b/ext/opcache/tests/internal_func_info_static_method.phpt new file mode 100644 index 00000000000..df4e9b2aab6 --- /dev/null +++ b/ext/opcache/tests/internal_func_info_static_method.phpt @@ -0,0 +1,14 @@ +--TEST-- +Internal static methods should not be confused with global functions +--SKIPIF-- + +--FILE-- + +--EXPECT-- +bool(false) diff --git a/ext/zend_test/test.c b/ext/zend_test/test.c index 0ad566a025d..4a7fe540fb4 100644 --- a/ext/zend_test/test.c +++ b/ext/zend_test/test.c @@ -149,17 +149,20 @@ static zend_function *zend_test_class_method_get(zend_object **object, zend_stri /* }}} */ 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); + if (zend_string_equals_literal_ci(name, "test")) { + 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; + return (zend_function*)fptr; + } + return zend_std_get_static_method(ce, name, NULL); } /* }}} */ @@ -169,11 +172,22 @@ static int zend_test_class_call_method(zend_string *method, zend_object *object, } /* }}} */ +/* Internal function returns bool, we return int. */ +static ZEND_METHOD(_ZendTestClass, is_object) /* {{{ */ { + RETURN_LONG(42); +} +/* }}} */ + static ZEND_METHOD(_ZendTestTrait, testMethod) /* {{{ */ { RETURN_TRUE; } /* }}} */ +static const zend_function_entry zend_test_class_methods[] = { + ZEND_ME(_ZendTestClass, is_object, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) + ZEND_FE_END +}; + static zend_function_entry zend_test_trait_methods[] = { ZEND_ME(_ZendTestTrait, testMethod, NULL, ZEND_ACC_PUBLIC) ZEND_FE_END @@ -186,7 +200,7 @@ PHP_MINIT_FUNCTION(zend_test) 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); + INIT_CLASS_ENTRY(class_entry, "_ZendTestClass", zend_test_class_methods); 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;