[php-src] master: Merge branch 'PHP-8.6'

From: Date: Wed, 30 Sep 2026 15:07:09 +0000
Subject: [php-src] master: Merge branch 'PHP-8.6'
Groups: php.cvs 
Request: Send a blank email to php-cvs+get-141802@lists.php.net to get a copy of this message
Author: Ilia Alshanetsky (iliaal) Date: 2026-09-30T11:00:02-04:00 Commit: https://github.com/php/php-src/commit/777de89757b79476157683291e4b9487e8a7f9af Raw diff: https://github.com/php/php-src/commit/777de89757b79476157683291e4b9487e8a7f9af.diff Merge branch 'PHP-8.6' * PHP-8.6: Zend: Skip frameless registration for temporary modules Changed paths: A ext/dl_test/tests/frameless_temporary.inc A ext/dl_test/tests/frameless_temporary.phpt A ext/dl_test/tests/frameless_temporary_cgi.inc A ext/dl_test/tests/frameless_temporary_opcache.phpt M Zend/zend_API.c M ext/dl_test/dl_test.c M ext/dl_test/dl_test.stub.php M ext/dl_test/dl_test_arginfo.h Diff: diff --git a/Zend/zend_API.c b/Zend/zend_API.c index db20926dd96d..f0b45a64ba98 100644 --- a/Zend/zend_API.c +++ b/Zend/zend_API.c @@ -3088,7 +3088,11 @@ ZEND_API zend_result zend_register_functions(zend_class_entry *scope, const zend internal_function->prototype = NULL; internal_function->prop_info = NULL; internal_function->attributes = NULL; - internal_function->frameless_function_infos = ptr->frameless_function_infos; + if (type == MODULE_TEMPORARY) { + internal_function->frameless_function_infos = NULL; + } else { + internal_function->frameless_function_infos = ptr->frameless_function_infos; + } if (EG(active)) { // at run-time: this ought to only happen if registered with dl() or somehow temporarily at runtime ZEND_MAP_PTR_INIT(internal_function->run_time_cache, zend_arena_calloc(&CG(arena), 1, zend_internal_run_time_cache_reserved_size())); } else { diff --git a/ext/dl_test/dl_test.c b/ext/dl_test/dl_test.c index 4346e868c1e5..c96449aebc10 100644 --- a/ext/dl_test/dl_test.c +++ b/ext/dl_test/dl_test.c @@ -50,6 +50,28 @@ PHP_FUNCTION(dl_test_test2) } /* }}}*/ +PHP_FUNCTION(dl_test_frameless) +{ + zend_long value; + + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_LONG(value) + ZEND_PARSE_PARAMETERS_END(); + + RETURN_LONG(value); +} + +ZEND_FRAMELESS_FUNCTION(dl_test_frameless, 1) +{ + zend_long value; + + Z_FLF_PARAM_LONG(1, value); + + RETVAL_LONG(value); + +flf_clean:; +} + /* {{{ PHP_DL_TEST_USE_REGISTER_FUNCTIONS_DIRECTLY */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_dl_test_use_register_functions_directly, 0, 0, IS_STRING, 0) ZEND_END_ARG_INFO() diff --git a/ext/dl_test/dl_test.stub.php b/ext/dl_test/dl_test.stub.php index 42a30f233f57..ad2de67fb6de 100644 --- a/ext/dl_test/dl_test.stub.php +++ b/ext/dl_test/dl_test.stub.php @@ -11,6 +11,11 @@ function dl_test_test1(): void {} function dl_test_test2(string $str = ""): string {} +/** + * @frameless-function {"arity": 1} + */ +function dl_test_frameless(int $value): int {} + 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 800d4fe8dd35..f659696e4e7c 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 dl_test.stub.php instead. - * Stub hash: 3c47a0da41b4548eb68c4124bd54cbac22f60c01 */ + * Stub hash: f935fbfb32fd8d960437269566d6bcaa3be7b6b0 */ #include "zend_constants.h" @@ -10,18 +10,31 @@ 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() +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_dl_test_frameless, 0, 1, IS_LONG, 0) + ZEND_ARG_TYPE_INFO(0, value, IS_LONG, 0) +ZEND_END_ARG_INFO() + #define arginfo_class_DlTest_test arginfo_dl_test_test2 #define arginfo_class_DlTestSuperClass_test arginfo_dl_test_test2 + +ZEND_FRAMELESS_FUNCTION(dl_test_frameless, 1); +static const zend_frameless_function_info frameless_function_infos_dl_test_frameless[] = { + { ZEND_FRAMELESS_FUNCTION_NAME(dl_test_frameless, 1), 1 }, + { 0 }, +}; + ZEND_FUNCTION(dl_test_test1); ZEND_FUNCTION(dl_test_test2); +ZEND_FUNCTION(dl_test_frameless); ZEND_METHOD(DlTest, test); ZEND_METHOD(DlTestSuperClass, test); static const zend_function_entry ext_functions[] = { ZEND_FE(dl_test_test1, arginfo_dl_test_test1) ZEND_FE(dl_test_test2, arginfo_dl_test_test2) + ZEND_RAW_FENTRY("dl_test_frameless", zif_dl_test_frameless, arginfo_dl_test_frameless, 0, frameless_function_infos_dl_test_frameless, NULL) ZEND_FE_END }; diff --git a/ext/dl_test/tests/frameless_temporary.inc b/ext/dl_test/tests/frameless_temporary.inc new file mode 100644 index 000000000000..8b452a5e8dce --- /dev/null +++ b/ext/dl_test/tests/frameless_temporary.inc @@ -0,0 +1,8 @@ +<?php +var_dump(dl_test_frameless(7)); +try { + dl_test_frameless("nope"); + echo "no throw\n"; +} catch (TypeError $e) { + echo $e->getMessage(), "\n"; +} diff --git a/ext/dl_test/tests/frameless_temporary.phpt b/ext/dl_test/tests/frameless_temporary.phpt new file mode 100644 index 000000000000..fe38123d99e8 --- /dev/null +++ b/ext/dl_test/tests/frameless_temporary.phpt @@ -0,0 +1,53 @@ +--TEST-- +dl() of a frameless function does not keep the freed function record +--SKIPIF-- +<?php +if (PHP_OS_FAMILY === 'Windows') { + die('skip setarch -R is required so dl() remaps the extension at the stale handler address'); +} +if (!getenv('TEST_PHP_CGI_EXECUTABLE')) { + die('skip php-cgi not available'); +} +$setarch = trim((string) shell_exec('command -v setarch')); +if ($setarch === '') { + die('skip setarch -R is required so dl() remaps the extension at the stale handler address'); +} +$arch = php_uname('m'); +exec($setarch . ' ' . escapeshellarg($arch) . ' -R true', $setarch_out, $setarch_code); +if ($setarch_code !== 0) { + die('skip setarch -R cannot run on ' . $arch); +} +$so = ini_get('extension_dir') . DIRECTORY_SEPARATOR . 'dl_test.so'; +if (!file_exists($so)) { + die('skip dl_test extension is not built (tried ' . $so . ')'); +} +?> +--FILE-- +<?php +$cmd = 'env -u SCRIPT_FILENAME -u PATH_TRANSLATED -u REDIRECT_STATUS -u REQUEST_METHOD -u QUERY_STRING' + . ' USE_ZEND_ALLOC=0 ASAN_OPTIONS=' . escapeshellarg('detect_leaks=0:halt_on_error=1:abort_on_error=1') + . ' setarch ' . escapeshellarg(php_uname('m')) . ' -R ' + . escapeshellarg(getenv('TEST_PHP_CGI_EXECUTABLE')) + . ' -n -q -T 2 -d enable_dl=1 -d extension_dir=' . escapeshellarg(ini_get('extension_dir')) + . ' ' . escapeshellarg(__DIR__ . '/frameless_temporary_cgi.inc'); +$proc = proc_open($cmd, [ + 0 => ['pipe', 'r'], + 1 => ['pipe', 'w'], + 2 => ['pipe', 'w'], +], $pipes); +fclose($pipes[0]); +$out = stream_get_contents($pipes[1]); +stream_get_contents($pipes[2]); +fclose($pipes[1]); +fclose($pipes[2]); +echo $out; +$code = proc_close($proc); +if ($code !== 0) { + echo "exit:$code\n"; +} +?> +--EXPECT-- +int(7) +dl_test_frameless(): Argument #1 ($value) must be of type int, string given +int(7) +dl_test_frameless(): Argument #1 ($value) must be of type int, string given diff --git a/ext/dl_test/tests/frameless_temporary_cgi.inc b/ext/dl_test/tests/frameless_temporary_cgi.inc new file mode 100644 index 000000000000..a5a9398f0e4a --- /dev/null +++ b/ext/dl_test/tests/frameless_temporary_cgi.inc @@ -0,0 +1,7 @@ +<?php +$ext = PHP_OS_FAMILY === 'Windows' ? 'php_dl_test.dll' : 'dl_test.so'; +if (!dl($ext)) { + echo "dl failed\n"; + return; +} +include __DIR__ . '/frameless_temporary.inc'; diff --git a/ext/dl_test/tests/frameless_temporary_opcache.phpt b/ext/dl_test/tests/frameless_temporary_opcache.phpt new file mode 100644 index 000000000000..547ee71d2145 --- /dev/null +++ b/ext/dl_test/tests/frameless_temporary_opcache.phpt @@ -0,0 +1,19 @@ +--TEST-- +dl() does not compile calls to a temporary module's function as frameless +--SKIPIF-- +<?php include __DIR__ . "/skip.inc"; ?> +--EXTENSIONS-- +opcache +--INI-- +enable_dl=1 +opcache.enable_cli=1 +opcache.opt_debug_level=0x10000 +--FILE-- +<?php +dl(PHP_OS_FAMILY === 'Windows' ? 'php_dl_test.dll' : 'dl_test.so'); +include __DIR__ . '/frameless_temporary.inc'; +?> +--EXPECTF-- +%A0001 INIT_FCALL 1 %d string("dl_test_frameless") +%Aint(7) +dl_test_frameless(): Argument #1 ($value) must be of type int, string given

« previous php.cvs (#141802) next »