Skip to content

Commit f07a08d

Browse files
authored
Fix unregistering ini entries of dynamically loaded extension (php#8435)
Fixes phpGH-8185
1 parent b2be889 commit f07a08d

File tree

23 files changed

+408
-14
lines changed

23 files changed

+408
-14
lines changed

.cirrus.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ task:
1414
- pkg install -y autoconf bison gmake re2c icu libiconv png freetype2 enchant2 bzip2 krb5 t1lib gmp tidyp libsodium libzip libxml2 libxslt openssl oniguruma pkgconf webp libavif
1515
script:
1616
- ./buildconf -f
17-
- ./configure --prefix=/usr/local --enable-debug --enable-option-checking=fatal --enable-fpm --with-pdo-sqlite --without-pear --with-bz2 --with-avif --with-jpeg --with-webp --with-freetype --enable-gd --enable-exif --with-zip --with-zlib --enable-soap --enable-xmlreader --with-xsl --with-libxml --enable-shmop --enable-pcntl --enable-mbstring --with-curl --enable-sockets --with-openssl --with-iconv=/usr/local --enable-bcmath --enable-calendar --enable-ftp --with-kerberos --with-ffi --enable-zend-test --enable-intl --with-mhash --with-sodium --enable-werror --with-config-file-path=/etc --with-config-file-scan-dir=/etc/php.d
17+
- ./configure --prefix=/usr/local --enable-debug --enable-option-checking=fatal --enable-fpm --with-pdo-sqlite --without-pear --with-bz2 --with-avif --with-jpeg --with-webp --with-freetype --enable-gd --enable-exif --with-zip --with-zlib --enable-soap --enable-xmlreader --with-xsl --with-libxml --enable-shmop --enable-pcntl --enable-mbstring --with-curl --enable-sockets --with-openssl --with-iconv=/usr/local --enable-bcmath --enable-calendar --enable-ftp --with-kerberos --with-ffi --enable-zend-test --enable-dl-test=shared --enable-intl --with-mhash --with-sodium --enable-werror --with-config-file-path=/etc --with-config-file-scan-dir=/etc/php.d
1818
- gmake -j2
1919
- mkdir /etc/php.d
2020
- gmake install

.github/actions/configure-macos/action.yml

+1
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ runs:
6161
--enable-sysvmsg \
6262
--with-ffi \
6363
--enable-zend-test \
64+
--enable-dl-test=shared \
6465
--enable-intl \
6566
--with-mhash \
6667
--with-sodium \

.github/actions/configure-x64/action.yml

+1
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ runs:
5656
--enable-sysvmsg \
5757
--with-ffi \
5858
--enable-zend-test \
59+
--enable-dl-test=shared \
5960
--with-ldap \
6061
--with-ldap-sasl \
6162
--with-password-argon2 \

Zend/zend.c

+1-3
Original file line numberDiff line numberDiff line change
@@ -1033,9 +1033,7 @@ void zend_startup(zend_utility_functions *utility_functions) /* {{{ */
10331033

10341034
void zend_register_standard_ini_entries(void) /* {{{ */
10351035
{
1036-
int module_number = 0;
1037-
1038-
REGISTER_INI_ENTRIES();
1036+
zend_register_ini_entries_ex(ini_entries, 0, MODULE_PERSISTENT);
10391037
}
10401038
/* }}} */
10411039

Zend/zend_API.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -2965,7 +2965,7 @@ void module_destructor(zend_module_entry *module) /* {{{ */
29652965
if (module->module_started
29662966
&& !module->module_shutdown_func
29672967
&& module->type == MODULE_TEMPORARY) {
2968-
zend_unregister_ini_entries(module->module_number);
2968+
zend_unregister_ini_entries_ex(module->module_number, module->type);
29692969
}
29702970

29712971
/* Deinitialize module globals */

Zend/zend_ini.c

+44-3
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include "zend_alloc.h"
2424
#include "zend_operators.h"
2525
#include "zend_strtod.h"
26+
#include "zend_modules.h"
2627

2728
static HashTable *registered_zend_ini_directives;
2829

@@ -194,7 +195,7 @@ ZEND_API void zend_ini_sort_entries(void) /* {{{ */
194195
/*
195196
* Registration / unregistration
196197
*/
197-
ZEND_API zend_result zend_register_ini_entries(const zend_ini_entry_def *ini_entry, int module_number) /* {{{ */
198+
ZEND_API zend_result zend_register_ini_entries_ex(const zend_ini_entry_def *ini_entry, int module_number, int module_type) /* {{{ */
198199
{
199200
zend_ini_entry *p;
200201
zval *default_value;
@@ -210,7 +211,10 @@ ZEND_API zend_result zend_register_ini_entries(const zend_ini_entry_def *ini_ent
210211
* lead to death.
211212
*/
212213
if (directives != EG(ini_directives)) {
214+
ZEND_ASSERT(module_type == MODULE_TEMPORARY);
213215
directives = EG(ini_directives);
216+
} else {
217+
ZEND_ASSERT(module_type == MODULE_PERSISTENT);
214218
}
215219
#endif
216220

@@ -234,7 +238,7 @@ ZEND_API zend_result zend_register_ini_entries(const zend_ini_entry_def *ini_ent
234238
if (p->name) {
235239
zend_string_release_ex(p->name, 1);
236240
}
237-
zend_unregister_ini_entries(module_number);
241+
zend_unregister_ini_entries_ex(module_number, module_type);
238242
return FAILURE;
239243
}
240244
if (((default_value = zend_get_configuration_directive(p->name)) != NULL) &&
@@ -255,9 +259,46 @@ ZEND_API zend_result zend_register_ini_entries(const zend_ini_entry_def *ini_ent
255259
}
256260
/* }}} */
257261

262+
ZEND_API zend_result zend_register_ini_entries(const zend_ini_entry_def *ini_entry, int module_number) /* {{{ */
263+
{
264+
zend_module_entry *module;
265+
266+
/* Module is likely to be the last one in the list */
267+
ZEND_HASH_REVERSE_FOREACH_PTR(&module_registry, module) {
268+
if (module->module_number == module_number) {
269+
return zend_register_ini_entries_ex(ini_entry, module_number, module->type);
270+
}
271+
} ZEND_HASH_FOREACH_END();
272+
273+
return FAILURE;
274+
}
275+
/* }}} */
276+
277+
ZEND_API void zend_unregister_ini_entries_ex(int module_number, int module_type) /* {{{ */
278+
{
279+
static HashTable *ini_directives;
280+
281+
if (module_type == MODULE_TEMPORARY) {
282+
ini_directives = EG(ini_directives);
283+
} else {
284+
ini_directives = registered_zend_ini_directives;
285+
}
286+
287+
zend_hash_apply_with_argument(ini_directives, zend_remove_ini_entries, (void *) &module_number);
288+
}
289+
/* }}} */
290+
258291
ZEND_API void zend_unregister_ini_entries(int module_number) /* {{{ */
259292
{
260-
zend_hash_apply_with_argument(registered_zend_ini_directives, zend_remove_ini_entries, (void *) &module_number);
293+
zend_module_entry *module;
294+
295+
/* Module is likely to be the last one in the list */
296+
ZEND_HASH_REVERSE_FOREACH_PTR(&module_registry, module) {
297+
if (module->module_number == module_number) {
298+
zend_unregister_ini_entries_ex(module_number, module->type);
299+
return;
300+
}
301+
} ZEND_HASH_FOREACH_END();
261302
}
262303
/* }}} */
263304

Zend/zend_ini.h

+2
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,9 @@ ZEND_API void zend_copy_ini_directives(void);
7272
ZEND_API void zend_ini_sort_entries(void);
7373

7474
ZEND_API zend_result zend_register_ini_entries(const zend_ini_entry_def *ini_entry, int module_number);
75+
ZEND_API zend_result zend_register_ini_entries_ex(const zend_ini_entry_def *ini_entry, int module_number, int module_type);
7576
ZEND_API void zend_unregister_ini_entries(int module_number);
77+
ZEND_API void zend_unregister_ini_entries_ex(int module_number, int module_type);
7678
ZEND_API void zend_ini_refresh_caches(int stage);
7779
ZEND_API zend_result zend_alter_ini_entry(zend_string *name, zend_string *new_value, int modify_type, int stage);
7880
ZEND_API zend_result zend_alter_ini_entry_ex(zend_string *name, zend_string *new_value, int modify_type, int stage, bool force_change);

azure/configure.yml

+1
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ steps:
5050
--enable-sysvmsg \
5151
--with-ffi \
5252
--enable-zend-test \
53+
--enable-dl-test=shared \
5354
--with-ldap \
5455
--with-ldap-sasl \
5556
--with-password-argon2 \

azure/i386/job.yml

+1
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ jobs:
6262
--enable-sysvmsg \
6363
--with-ffi \
6464
--enable-zend-test \
65+
--enable-dl-test=shared \
6566
--with-mhash \
6667
--with-sodium \
6768
--enable-dba \

azure/msan_job.yml

+1
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ jobs:
4949
--enable-calendar \
5050
--enable-ftp \
5151
--enable-zend-test \
52+
--enable-dl-test=shared \
5253
--enable-werror \
5354
--enable-memory-sanitizer \
5455
--with-config-file-path=/etc \

build/Makefile.global

+4-1
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,10 @@ PHP_TEST_SETTINGS = -d 'open_basedir=' -d 'output_buffering=0' -d 'memory_limit=
7575
PHP_TEST_SHARED_EXTENSIONS = ` \
7676
if test "x$(PHP_MODULES)" != "x"; then \
7777
for i in $(PHP_MODULES)""; do \
78-
. $$i; $(top_srcdir)/build/shtool echo -n -- " -d extension=$$dlname"; \
78+
. $$i; \
79+
if test "x$$dlname" != "xdl_test.so"; then \
80+
$(top_srcdir)/build/shtool echo -n -- " -d extension=$$dlname"; \
81+
fi; \
7982
done; \
8083
fi; \
8184
if test "x$(PHP_ZEND_EX)" != "x"; then \

ext/dl_test/config.m4

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
PHP_ARG_ENABLE([dl-test],
2+
[whether to enable dl-test extension],
3+
[AS_HELP_STRING([--enable-dl-test],
4+
[Enable dl_test extension])])
5+
6+
if test "$PHP_DL_TEST" != "no"; then
7+
PHP_NEW_EXTENSION(dl_test, dl_test.c, [shared],, -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1)
8+
fi

ext/dl_test/config.w32

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// vim:ft=javascript
2+
3+
ARG_ENABLE("dl-test", "enable dl_test extension", "no");
4+
5+
if (PHP_DL_TEST != "no") {
6+
EXTENSION("dl_test", "dl_test.c", true, "/DZEND_ENABLE_STATIC_TSRMLS_CACHE=1");
7+
ADD_FLAG("CFLAGS_DL_TEST", "/D PHP_DL_TEST_EXPORTS ");
8+
}

ext/dl_test/dl_test.c

+146
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
/*
2+
+----------------------------------------------------------------------+
3+
| Copyright (c) The PHP Group |
4+
+----------------------------------------------------------------------+
5+
| This source file is subject to version 3.01 of the PHP license, |
6+
| that is bundled with this package in the file LICENSE, and is |
7+
| available through the world-wide-web at the following url: |
8+
| https://www.php.net/license/3_01.txt |
9+
| If you did not receive a copy of the PHP license and are unable to |
10+
| obtain it through the world-wide-web, please send a note to |
11+
| [email protected] so we can mail you a copy immediately. |
12+
+----------------------------------------------------------------------+
13+
| Author: Arnaud Le Blanc <[email protected]> |
14+
+----------------------------------------------------------------------+
15+
*/
16+
17+
#ifdef HAVE_CONFIG_H
18+
# include "config.h"
19+
#endif
20+
21+
#include "php.h"
22+
#include "ext/standard/info.h"
23+
#include "php_dl_test.h"
24+
#include "dl_test_arginfo.h"
25+
26+
ZEND_DECLARE_MODULE_GLOBALS(dl_test)
27+
28+
/* {{{ void dl_test_test1() */
29+
PHP_FUNCTION(dl_test_test1)
30+
{
31+
ZEND_PARSE_PARAMETERS_NONE();
32+
33+
php_printf("The extension %s is loaded and working!\r\n", "dl_test");
34+
}
35+
/* }}} */
36+
37+
/* {{{ string dl_test_test2( [ string $var ] ) */
38+
PHP_FUNCTION(dl_test_test2)
39+
{
40+
char *var = "World";
41+
size_t var_len = sizeof("World") - 1;
42+
zend_string *retval;
43+
44+
ZEND_PARSE_PARAMETERS_START(0, 1)
45+
Z_PARAM_OPTIONAL
46+
Z_PARAM_STRING(var, var_len)
47+
ZEND_PARSE_PARAMETERS_END();
48+
49+
retval = strpprintf(0, "Hello %s", var);
50+
51+
RETURN_STR(retval);
52+
}
53+
/* }}}*/
54+
55+
/* {{{ INI */
56+
PHP_INI_BEGIN()
57+
STD_PHP_INI_BOOLEAN("dl_test.long", "0", PHP_INI_ALL, OnUpdateLong, long_value, zend_dl_test_globals, dl_test_globals)
58+
STD_PHP_INI_ENTRY("dl_test.string", "hello", PHP_INI_ALL, OnUpdateString, string_value, zend_dl_test_globals, dl_test_globals)
59+
PHP_INI_END()
60+
/* }}} */
61+
62+
/* {{{ PHP_MINIT_FUNCTION */
63+
PHP_MINIT_FUNCTION(dl_test)
64+
{
65+
/* Test backwards compatibility */
66+
if (getenv("PHP_DL_TEST_USE_OLD_REGISTER_INI_ENTRIES")) {
67+
zend_register_ini_entries(ini_entries, module_number);
68+
} else {
69+
REGISTER_INI_ENTRIES();
70+
}
71+
72+
return SUCCESS;
73+
}
74+
/* }}} */
75+
76+
/* {{{ PHP_MSHUTDOWN_FUNCTION */
77+
static PHP_MSHUTDOWN_FUNCTION(dl_test)
78+
{
79+
/* Test backwards compatibility */
80+
if (getenv("PHP_DL_TEST_USE_OLD_REGISTER_INI_ENTRIES")) {
81+
zend_unregister_ini_entries(module_number);
82+
} else {
83+
UNREGISTER_INI_ENTRIES();
84+
}
85+
86+
return SUCCESS;
87+
}
88+
/* }}} */
89+
90+
/* {{{ PHP_RINIT_FUNCTION */
91+
PHP_RINIT_FUNCTION(dl_test)
92+
{
93+
#if defined(ZTS) && defined(COMPILE_DL_DL_TEST)
94+
ZEND_TSRMLS_CACHE_UPDATE();
95+
#endif
96+
97+
return SUCCESS;
98+
}
99+
/* }}} */
100+
101+
/* {{{ PHP_MINFO_FUNCTION */
102+
PHP_MINFO_FUNCTION(dl_test)
103+
{
104+
php_info_print_table_start();
105+
php_info_print_table_header(2, "dl_test support", "enabled");
106+
php_info_print_table_end();
107+
108+
DISPLAY_INI_ENTRIES();
109+
}
110+
/* }}} */
111+
112+
/* {{{ PHP_GINIT_FUNCTION */
113+
static PHP_GINIT_FUNCTION(dl_test)
114+
{
115+
#if defined(COMPILE_DL_DL_TEST) && defined(ZTS)
116+
ZEND_TSRMLS_CACHE_UPDATE();
117+
#endif
118+
memset(dl_test_globals, 0, sizeof(*dl_test_globals));
119+
}
120+
/* }}} */
121+
122+
/* {{{ dl_test_module_entry */
123+
zend_module_entry dl_test_module_entry = {
124+
STANDARD_MODULE_HEADER,
125+
"dl_test",
126+
ext_functions,
127+
PHP_MINIT(dl_test),
128+
PHP_MSHUTDOWN(dl_test),
129+
PHP_RINIT(dl_test),
130+
NULL,
131+
PHP_MINFO(dl_test),
132+
PHP_DL_TEST_VERSION,
133+
PHP_MODULE_GLOBALS(dl_test),
134+
PHP_GINIT(dl_test),
135+
NULL,
136+
NULL,
137+
STANDARD_MODULE_PROPERTIES_EX
138+
};
139+
/* }}} */
140+
141+
#ifdef COMPILE_DL_DL_TEST
142+
# ifdef ZTS
143+
ZEND_TSRMLS_CACHE_DEFINE()
144+
# endif
145+
ZEND_GET_MODULE(dl_test)
146+
#endif

ext/dl_test/dl_test.stub.php

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<?php
2+
3+
/** @generate-class-entries */
4+
5+
function dl_test_test1(): void {}
6+
7+
function dl_test_test2(string $str = ""): string {}

ext/dl_test/dl_test_arginfo.h

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
/* This is a generated file, edit the .stub.php file instead.
2+
* Stub hash: 39ccf8141b0eb785cafd490b420f2e99d6a7a66d */
3+
4+
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_dl_test_test1, 0, 0, IS_VOID, 0)
5+
ZEND_END_ARG_INFO()
6+
7+
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_dl_test_test2, 0, 0, IS_STRING, 0)
8+
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, str, IS_STRING, 0, "\"\"")
9+
ZEND_END_ARG_INFO()
10+
11+
12+
ZEND_FUNCTION(dl_test_test1);
13+
ZEND_FUNCTION(dl_test_test2);
14+
15+
16+
static const zend_function_entry ext_functions[] = {
17+
ZEND_FE(dl_test_test1, arginfo_dl_test_test1)
18+
ZEND_FE(dl_test_test2, arginfo_dl_test_test2)
19+
ZEND_FE_END
20+
};

0 commit comments

Comments
 (0)