[php-src] PHP-8.6: Merge branch 'PHP-8.5' into PHP-8.6
| From: | Ilia Alshanetsky | Date: | Fri, 02 Oct 2026 20:18:48 +0000 |
| Subject: | [php-src] PHP-8.6: Merge branch 'PHP-8.5' into PHP-8.6 | ||
| Groups: | php.cvs | ||
| Request: | Send a blank email to php-cvs+get-141895@lists.php.net to get a copy of this message | ||
Author: Ilia Alshanetsky (iliaal)
Date: 2026-10-02T16:17:21-04:00
Commit: https://github.com/php/php-src/commit/4e5516af1dae5adb5b42fe964341cbd6f82da195
Raw diff: https://github.com/php/php-src/commit/4e5516af1dae5adb5b42fe964341cbd6f82da195.diff
Merge branch 'PHP-8.5' into PHP-8.6
* PHP-8.5:
Zend: Include frameless functions in the system id
Changed paths:
A ext/opcache/tests/file_cache_frameless_handler.phpt
M NEWS
M Zend/zend_API.c
Diff:
diff --git a/NEWS b/NEWS
index 9eddfb8f9a10..f6f395444596 100644
--- a/NEWS
+++ b/NEWS
@@ -65,6 +65,8 @@ PHP NEWS
arnaud-lb)
. Fixed bug GH-24063 (OPcache optimizer folds
$cond ? -0.0 : 0.0 into a
single -0.0 constant). (lazerg)
+ . Fixed crash when a file cache is reused with a different set of
+ extensions declaring frameless functions. (Ilia Alshanetsky)
- OpenSSL:
. Fixed stream_socket_enable_crypto() leaving the socket non-blocking
diff --git a/Zend/zend_API.c b/Zend/zend_API.c
index 739bc9d240ea..accc7a513a0f 100644
--- a/Zend/zend_API.c
+++ b/Zend/zend_API.c
@@ -34,6 +34,7 @@
#include "zend_enum.h"
#include "zend_object_handlers.h"
#include "zend_observer.h"
+#include "zend_system_id.h"
#include <stdarg.h>
@@ -3223,6 +3224,7 @@ ZEND_API zend_result zend_register_functions(zend_class_entry *scope, const
zend
}
zend_flf_handlers[zend_flf_count] = flf_info->handler;
zend_flf_functions[zend_flf_count] = (zend_function *)reg_function;
+ zend_add_system_entropy("frameless", ZSTR_VAL(reg_function->function_name),
&flf_info->num_args, sizeof(flf_info->num_args));
zend_flf_count++;
flf_info++;
}
diff --git a/ext/opcache/tests/file_cache_frameless_handler.phpt
b/ext/opcache/tests/file_cache_frameless_handler.phpt
new file mode 100644
index 000000000000..eb557f1e718c
--- /dev/null
+++ b/ext/opcache/tests/file_cache_frameless_handler.phpt
@@ -0,0 +1,81 @@
+--TEST--
+opcache file cache must not reuse frameless function indices across extension sets
+--EXTENSIONS--
+opcache
+--SKIPIF--
+<?php
+$dl_test = PHP_OS_FAMILY === 'Windows' ? 'php_dl_test.dll' :
'dl_test.so';
+if (!file_exists(ini_get('extension_dir') . DIRECTORY_SEPARATOR . $dl_test)) {
+ die('skip dl_test extension is not built');
+}
+?>
+--FILE--
+<?php
+$cache = __DIR__ . DIRECTORY_SEPARATOR . 'file_cache_frameless_handler';
+$script = $cache . DIRECTORY_SEPARATOR . 'call.php';
+mkdir($cache);
+file_put_contents($script, <<<'PHP'
+<?php
+if (isset($argv[1])) {
+ dl('dl_test');
+}
+try {
+ var_dump(dl_test_frameless(7));
+} catch (Error $e) {
+ echo $e::class, ": ", $e->getMessage(), "\n";
+}
+PHP);
+
+function run(string $cache, array $args): void {
+ $ext = ini_get('extension_dir');
+ $opcache = PHP_OS_FAMILY === 'Windows' ? 'php_opcache.dll' :
'opcache.so';
+ $cmd = [PHP_BINARY, '-n', '-d', 'extension_dir="' . $ext .
'"'];
+ if (file_exists($ext . DIRECTORY_SEPARATOR . $opcache)) {
+ array_push($cmd, '-d', 'zend_extension=opcache');
+ }
+ array_push($cmd,
+ '-d', 'opcache.enable_cli=1',
+ '-d', 'opcache.file_cache="' . $cache . '"',
+ '-d', 'opcache.file_cache_only=1',
+ '-d', 'opcache.file_update_protection=0',
+ ...$args,
+ );
+ $proc = proc_open($cmd, [1 => ['pipe', 'w'], 2 => ['pipe',
'w']], $pipes);
+ echo stream_get_contents($pipes[1]);
+ stream_get_contents($pipes[2]);
+ proc_close($proc);
+}
+
+function system_ids(string $cache): int {
+ $pattern = PHP_OS_FAMILY === 'Windows' ? '/*/*' : '/*';
+ return count(glob($cache . $pattern, GLOB_ONLYDIR));
+}
+
+run($cache, ['-d', 'extension=dl_test', $script]);
+var_dump(system_ids($cache));
+run($cache, [$script, 'dl']);
+var_dump(system_ids($cache));
+run($cache, [$script]);
+var_dump(system_ids($cache));
+?>
+--CLEAN--
+<?php
+$cache = __DIR__ . DIRECTORY_SEPARATOR . 'file_cache_frameless_handler';
+if (is_dir($cache)) {
+ $it = new RecursiveIteratorIterator(
+ new RecursiveDirectoryIterator($cache, FilesystemIterator::SKIP_DOTS),
+ RecursiveIteratorIterator::CHILD_FIRST
+ );
+ foreach ($it as $file) {
+ $file->isDir() ? rmdir($file->getPathname()) : unlink($file->getPathname());
+ }
+ rmdir($cache);
+}
+?>
+--EXPECT--
+int(7)
+int(1)
+int(7)
+int(2)
+Error: Call to undefined function dl_test_frameless()
+int(2)