Skip to content

Commit 37d848c

Browse files
committed
Fix GH-9921: Loading ext in FPM config does not register module handlers
Closes GH-12377
1 parent 240a3b3 commit 37d848c

File tree

5 files changed

+101
-5
lines changed

5 files changed

+101
-5
lines changed

Zend/zend_API.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2326,10 +2326,15 @@ ZEND_API void zend_startup_modules(void) /* {{{ */
23262326
}
23272327
/* }}} */
23282328

2329-
ZEND_API void zend_destroy_modules(void) /* {{{ */
2329+
ZEND_API void zend_destroy_module_handlers(void)
23302330
{
23312331
free(class_cleanup_handlers);
23322332
free(module_request_startup_handlers);
2333+
}
2334+
2335+
ZEND_API void zend_destroy_modules(void) /* {{{ */
2336+
{
2337+
zend_destroy_module_handlers();
23332338
zend_hash_graceful_reverse_destroy(&module_registry);
23342339
}
23352340
/* }}} */

Zend/zend_API.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -361,6 +361,7 @@ ZEND_API zend_module_entry* zend_register_module_ex(zend_module_entry *module);
361361
ZEND_API zend_result zend_startup_module_ex(zend_module_entry *module);
362362
ZEND_API void zend_startup_modules(void);
363363
ZEND_API void zend_collect_module_handlers(void);
364+
ZEND_API void zend_destroy_module_handlers(void);
364365
ZEND_API void zend_destroy_modules(void);
365366
ZEND_API void zend_check_magic_method_implementation(
366367
const zend_class_entry *ce, const zend_function *fptr, zend_string *lcname, int error_type);

ext/dl_test/dl_test.c

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,10 @@ PHP_MINIT_FUNCTION(dl_test)
6969
REGISTER_INI_ENTRIES();
7070
}
7171

72+
if (getenv("PHP_DL_TEST_MODULE_DEBUG")) {
73+
fprintf(stderr, "DL TEST MINIT\n");
74+
}
75+
7276
return SUCCESS;
7377
}
7478
/* }}} */
@@ -83,6 +87,10 @@ static PHP_MSHUTDOWN_FUNCTION(dl_test)
8387
UNREGISTER_INI_ENTRIES();
8488
}
8589

90+
if (getenv("PHP_DL_TEST_MODULE_DEBUG")) {
91+
fprintf(stderr, "DL TEST MSHUTDOWN\n");
92+
}
93+
8694
return SUCCESS;
8795
}
8896
/* }}} */
@@ -94,6 +102,21 @@ PHP_RINIT_FUNCTION(dl_test)
94102
ZEND_TSRMLS_CACHE_UPDATE();
95103
#endif
96104

105+
if (getenv("PHP_DL_TEST_MODULE_DEBUG")) {
106+
fprintf(stderr, "DL TEST RINIT\n");
107+
}
108+
109+
return SUCCESS;
110+
}
111+
/* }}} */
112+
113+
/* {{{ PHP_RSHUTDOWN_FUNCTION */
114+
PHP_RSHUTDOWN_FUNCTION(dl_test)
115+
{
116+
if (getenv("PHP_DL_TEST_MODULE_DEBUG")) {
117+
fprintf(stderr, "DL TEST RSHUTDOWN\n");
118+
}
119+
97120
return SUCCESS;
98121
}
99122
/* }}} */
@@ -127,7 +150,7 @@ zend_module_entry dl_test_module_entry = {
127150
PHP_MINIT(dl_test),
128151
PHP_MSHUTDOWN(dl_test),
129152
PHP_RINIT(dl_test),
130-
NULL,
153+
PHP_RSHUTDOWN(dl_test),
131154
PHP_MINFO(dl_test),
132155
PHP_DL_TEST_VERSION,
133156
PHP_MODULE_GLOBALS(dl_test),

sapi/fpm/fpm/fpm_php.c

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ int fpm_php_apply_defines_ex(struct key_value_s *kv, int mode) /* {{{ */
9090
zend_interned_strings_switch_storage(0);
9191
php_dl(value, MODULE_PERSISTENT, &zv, 1);
9292
zend_interned_strings_switch_storage(1);
93-
return Z_TYPE(zv) == IS_TRUE;
93+
return Z_TYPE(zv) == IS_TRUE ? 2 : 0;
9494
}
9595

9696
if (fpm_php_zend_ini_alter_master(name, name_len, value, value_len, mode, PHP_INI_STAGE_ACTIVATE) == FAILURE) {
@@ -116,19 +116,32 @@ int fpm_php_apply_defines_ex(struct key_value_s *kv, int mode) /* {{{ */
116116
static int fpm_php_apply_defines(struct fpm_worker_pool_s *wp) /* {{{ */
117117
{
118118
struct key_value_s *kv;
119+
int apply_result;
120+
bool extension_loaded = false;
119121

120122
for (kv = wp->config->php_values; kv; kv = kv->next) {
121-
if (fpm_php_apply_defines_ex(kv, ZEND_INI_USER) == -1) {
123+
apply_result = fpm_php_apply_defines_ex(kv, ZEND_INI_USER);
124+
if (apply_result == -1) {
122125
zlog(ZLOG_ERROR, "Unable to set php_value '%s'", kv->key);
126+
} else if (apply_result == 2) {
127+
extension_loaded = true;
123128
}
124129
}
125130

126131
for (kv = wp->config->php_admin_values; kv; kv = kv->next) {
127-
if (fpm_php_apply_defines_ex(kv, ZEND_INI_SYSTEM) == -1) {
132+
apply_result = fpm_php_apply_defines_ex(kv, ZEND_INI_SYSTEM);
133+
if (apply_result == -1) {
128134
zlog(ZLOG_ERROR, "Unable to set php_admin_value '%s'", kv->key);
135+
} else if (apply_result == 2) {
136+
extension_loaded = true;
129137
}
130138
}
131139

140+
if (extension_loaded) {
141+
zend_destroy_module_handlers();
142+
zend_collect_module_handlers();
143+
}
144+
132145
return 0;
133146
}
134147
/* }}} */
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
--TEST--
2+
FPM: GH-9921 - loading shared ext in FPM config does not register module handlers
3+
--SKIPIF--
4+
<?php
5+
include "skipif.inc";
6+
FPM\Tester::skipIfSharedExtensionNotFound('dl_test');
7+
?>
8+
--FILE--
9+
<?php
10+
11+
require_once "tester.inc";
12+
13+
$cfg = <<<EOT
14+
[global]
15+
error_log = {{FILE:LOG}}
16+
[unconfined]
17+
listen = {{ADDR}}
18+
pm = static
19+
pm.max_children = 1
20+
pm.status_path = /status
21+
catch_workers_output = yes
22+
env[PHP_DL_TEST_MODULE_DEBUG] = 1
23+
php_admin_value[extension] = dl_test
24+
EOT;
25+
26+
$code = <<<EOT
27+
<?php
28+
var_dump(extension_loaded('dl_test'));
29+
EOT;
30+
31+
$tester = new FPM\Tester($cfg, $code);
32+
$tester->start();
33+
$tester->expectLogStartNotices();
34+
$tester->request()->expectBody('bool(true)');
35+
$tester->expectLogPattern('/DL TEST MINIT/');
36+
$tester->expectLogPattern('/DL TEST RINIT/');
37+
$tester->expectLogPattern('/DL TEST RSHUTDOWN/');
38+
$tester->request()->expectBody('bool(true)');
39+
$tester->expectLogPattern('/DL TEST RINIT/');
40+
$tester->expectLogPattern('/DL TEST RSHUTDOWN/');
41+
$tester->terminate();
42+
$tester->expectLogTerminatingNotices();
43+
$tester->close();
44+
45+
?>
46+
Done
47+
--EXPECT--
48+
Done
49+
--CLEAN--
50+
<?php
51+
require_once "tester.inc";
52+
FPM\Tester::clean();
53+
?>
54+
<?php

0 commit comments

Comments
 (0)