diff --git a/NEWS b/NEWS index cb27125a7e1..c03d6879330 100644 --- a/NEWS +++ b/NEWS @@ -8,6 +8,8 @@ PHP NEWS (nielsdos) . Fixed bug GH-17101 (AST->string does not reproduce constructor property promotion correctly). (nielsdos) + . Fixed bug GH-17211 (observer segfault on function loaded with dl()). + (Arnaud) - Date: . Fixed bug GH-14709 DatePeriod::__construct() overflow on recurrences. diff --git a/Zend/zend_API.c b/Zend/zend_API.c index e93c4a93b7d..13c640a64dd 100644 --- a/Zend/zend_API.c +++ b/Zend/zend_API.c @@ -2817,7 +2817,14 @@ ZEND_API zend_result zend_register_functions(zend_class_entry *scope, const zend } internal_function->type = ZEND_INTERNAL_FUNCTION; internal_function->module = EG(current_module); - internal_function->T = 0; + if (EG(active) && ZEND_OBSERVER_ENABLED) { + /* Add an observer temporary to store previous observed frames. This is + * normally handled by zend_observer_post_startup(), except for + * functions registered at runtime (EG(active)). */ + internal_function->T = 1; + } else { + internal_function->T = 0; + } memset(internal_function->reserved, 0, ZEND_MAX_RESERVED_RESOURCES * sizeof(void*)); while (ptr->fname) { diff --git a/ext/dl_test/dl_test.c b/ext/dl_test/dl_test.c index 5a5dfee33f5..1121a96b9df 100644 --- a/ext/dl_test/dl_test.c +++ b/ext/dl_test/dl_test.c @@ -76,9 +76,27 @@ PHP_INI_BEGIN() PHP_INI_END() /* }}} */ +PHP_METHOD(DlTest, test) +{ + char *var = "World"; + size_t var_len = sizeof("World") - 1; + zend_string *retval; + + ZEND_PARSE_PARAMETERS_START(0, 1) + Z_PARAM_OPTIONAL + Z_PARAM_STRING(var, var_len) + ZEND_PARSE_PARAMETERS_END(); + + retval = strpprintf(0, "Hello %s", var); + + RETURN_STR(retval); +} + /* {{{ PHP_MINIT_FUNCTION */ PHP_MINIT_FUNCTION(dl_test) { + register_class_DlTest(); + /* Test backwards compatibility */ if (getenv("PHP_DL_TEST_USE_OLD_REGISTER_INI_ENTRIES")) { zend_register_ini_entries(ini_entries, module_number); diff --git a/ext/dl_test/dl_test.stub.php b/ext/dl_test/dl_test.stub.php index 524c8206365..cd8b3916bae 100644 --- a/ext/dl_test/dl_test.stub.php +++ b/ext/dl_test/dl_test.stub.php @@ -8,3 +8,7 @@ function dl_test_test1(): void {} function dl_test_test2(string $str = ""): string {} + +class DlTest { + public function test(string $str = ""): string {} +} diff --git a/ext/dl_test/dl_test_arginfo.h b/ext/dl_test/dl_test_arginfo.h index fdd0e3a89e1..0618bbdb222 100644 --- a/ext/dl_test/dl_test_arginfo.h +++ b/ext/dl_test/dl_test_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 547ddbc21e9aa853b491cb17e902bbbb9cc2df00 */ + * Stub hash: 2dbacf5282b0f8e53923ac70495c2da43c7237e3 */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_dl_test_test1, 0, 0, IS_VOID, 0) ZEND_END_ARG_INFO() @@ -8,9 +8,12 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_dl_test_test2, 0, 0, IS_STRING, ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, str, IS_STRING, 0, "\"\"") ZEND_END_ARG_INFO() +#define arginfo_class_DlTest_test arginfo_dl_test_test2 + ZEND_FUNCTION(dl_test_test1); ZEND_FUNCTION(dl_test_test2); +ZEND_METHOD(DlTest, test); static const zend_function_entry ext_functions[] = { @@ -18,3 +21,19 @@ static const zend_function_entry ext_functions[] = { ZEND_FE(dl_test_test2, arginfo_dl_test_test2) ZEND_FE_END }; + + +static const zend_function_entry class_DlTest_methods[] = { + ZEND_ME(DlTest, test, arginfo_class_DlTest_test, ZEND_ACC_PUBLIC) + ZEND_FE_END +}; + +static zend_class_entry *register_class_DlTest(void) +{ + zend_class_entry ce, *class_entry; + + INIT_CLASS_ENTRY(ce, "DlTest", class_DlTest_methods); + class_entry = zend_register_internal_class_ex(&ce, NULL); + + return class_entry; +} diff --git a/ext/standard/tests/general_functions/gh17211.phpt b/ext/standard/tests/general_functions/gh17211.phpt new file mode 100644 index 00000000000..5df8a6638a6 --- /dev/null +++ b/ext/standard/tests/general_functions/gh17211.phpt @@ -0,0 +1,42 @@ +--TEST-- +dl() / observer segfault +--EXTENSIONS-- +zend_test +--SKIPIF-- + +--INI-- +zend_test.observer.enabled=1 +zend_test.observer.observe_functions=1 +zend_test.observer.show_output=1 +--FILE-- +test("World!")); +?> +--EXPECTF-- + + +