Skip to content

Commit 02d966c

Browse files
author
Jani Taskinen
committed
MFH:- Added support for [HOST=www.example.com] special sections
MFH:- Allowed using full path to load modules using "extension" directive
1 parent c5776e1 commit 02d966c

File tree

6 files changed

+85
-57
lines changed

6 files changed

+85
-57
lines changed

NEWS

+4-3
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,11 @@ PHP NEWS
2525

2626
- Improved php.ini handling: (Jani)
2727
. Added ".htaccess" style user-defined php.ini files support for CGI/FastCGI
28-
. Added support for special [PATH=/opt/httpd/www.example.com/] sections
29-
All directives set in these sections will not be able to be overridden
30-
in user-defined ini-files or during runtime in the specified path
28+
. Added support for special [PATH=/opt/httpd/www.example.com/] and
29+
[HOST=www.example.com] sections. Directives set in these sections can
30+
not be overridden by user-defined ini-files or during runtime.
3131
. Added better error reporting for php.ini syntax errors
32+
. Allowed using full path to load modules using "extension" directive
3233
. Allowed "ini-variables" to be used almost everywhere ini php.ini files
3334
. Allowed using alphanumeric/variable indexes in "array" ini options
3435
. Added 3rd optional parameter to parse_ini_file() to specify the scanning

ext/standard/dl.c

+38-28
Original file line numberDiff line numberDiff line change
@@ -77,10 +77,10 @@ PHP_FUNCTION(dl)
7777
(strncmp(sapi_module.name, "embed", 5) != 0)
7878
) {
7979
#ifdef ZTS
80-
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Not supported in multithreaded Web servers - use extension=%s in your php.ini", Z_STRVAL_PP(file));
80+
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Not supported in multithreaded Web servers - use extension=%s in your php.ini", Z_STRVAL_P(filename));
8181
RETURN_FALSE;
8282
#else
83-
php_error_docref(NULL TSRMLS_CC, E_STRICT, "dl() is deprecated - use extension=%s in your php.ini", Z_STRVAL_PP(file));
83+
php_error_docref(NULL TSRMLS_CC, E_STRICT, "dl() is deprecated - use extension=%s in your php.ini", Z_STRVAL_P(filename));
8484
#endif
8585
}
8686

@@ -97,18 +97,14 @@ PHP_FUNCTION(dl)
9797
#define USING_ZTS 0
9898
#endif
9999

100-
/* {{{ php_dl
101-
*/
102-
void php_dl(zval *file, int type, zval *return_value, int start_now TSRMLS_DC)
100+
PHPAPI int php_load_extension(char *filename, int type, int start_now TSRMLS_DC) /* {{{ */
103101
{
104102
void *handle;
105103
char *libpath;
106104
zend_module_entry *module_entry;
107105
zend_module_entry *(*get_module)(void);
108106
int error_type;
109107
char *extension_dir;
110-
char *filename;
111-
int filename_len;
112108

113109
if (type == MODULE_PERSISTENT) {
114110
extension_dir = INI_STR("extension_dir");
@@ -122,26 +118,24 @@ void php_dl(zval *file, int type, zval *return_value, int start_now TSRMLS_DC)
122118
error_type = E_CORE_WARNING;
123119
}
124120

125-
filename = Z_STRVAL_P(file);
126-
filename_len = Z_STRLEN_P(file);
127-
128-
if (extension_dir && extension_dir[0]){
129-
int extension_dir_len = strlen(extension_dir);
130-
121+
/* Check if passed filename contains directory separators */
122+
if (strchr(filename, '/') != NULL || strchr(filename, DEFAULT_SLASH) != NULL) {
123+
/* Passing modules with full path is not supported for dynamically loaded extensions */
131124
if (type == MODULE_TEMPORARY) {
132-
if (strchr(filename, '/') != NULL || strchr(filename, DEFAULT_SLASH) != NULL) {
133-
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Temporary module name should contain only filename");
134-
RETURN_FALSE;
135-
}
125+
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Temporary module name should contain only filename");
126+
return FAILURE;
136127
}
128+
libpath = estrdup(filename);
129+
} else if (extension_dir && extension_dir[0]) {
130+
int extension_dir_len = strlen(extension_dir);
137131

138132
if (IS_SLASH(extension_dir[extension_dir_len-1])) {
139133
spprintf(&libpath, 0, "%s%s", extension_dir, filename); /* SAFE */
140134
} else {
141135
spprintf(&libpath, 0, "%s%c%s", extension_dir, DEFAULT_SLASH, filename); /* SAFE */
142136
}
143137
} else {
144-
libpath = estrndup(filename, filename_len);
138+
return FAILURE; /* Not full path given or extension_dir is not set */
145139
}
146140

147141
/* load dynamic symbol */
@@ -150,9 +144,8 @@ void php_dl(zval *file, int type, zval *return_value, int start_now TSRMLS_DC)
150144
php_error_docref(NULL TSRMLS_CC, error_type, "Unable to load dynamic library '%s' - %s", libpath, GET_DL_ERROR());
151145
GET_DL_ERROR(); /* free the buffer storing the error */
152146
efree(libpath);
153-
RETURN_FALSE;
147+
return FAILURE;
154148
}
155-
156149
efree(libpath);
157150

158151
get_module = (zend_module_entry *(*)(void)) DL_FETCH_SYMBOL(handle, "get_module");
@@ -167,8 +160,8 @@ void php_dl(zval *file, int type, zval *return_value, int start_now TSRMLS_DC)
167160

168161
if (!get_module) {
169162
DL_UNLOAD(handle);
170-
php_error_docref(NULL TSRMLS_CC, error_type, "Invalid library (maybe not a PHP library) '%s' ", filename);
171-
RETURN_FALSE;
163+
php_error_docref(NULL TSRMLS_CC, error_type, "Invalid library (maybe not a PHP library) '%s'", filename);
164+
return FAILURE;
172165
}
173166
module_entry = get_module();
174167
if ((module_entry->zend_debug != ZEND_DEBUG) ||
@@ -222,30 +215,47 @@ void php_dl(zval *file, int type, zval *return_value, int start_now TSRMLS_DC)
222215
name, zend_api, zend_debug, zts,
223216
ZEND_MODULE_API_NO, ZEND_DEBUG, USING_ZTS);
224217
DL_UNLOAD(handle);
225-
RETURN_FALSE;
218+
return FAILURE;
226219
}
227220
module_entry->type = type;
228221
module_entry->module_number = zend_next_free_module();
229222
module_entry->handle = handle;
230223

231224
if ((module_entry = zend_register_module_ex(module_entry TSRMLS_CC)) == NULL) {
232225
DL_UNLOAD(handle);
233-
RETURN_FALSE;
226+
return FAILURE;
234227
}
235228

236229
if ((type == MODULE_TEMPORARY || start_now) && zend_startup_module_ex(module_entry TSRMLS_CC) == FAILURE) {
237230
DL_UNLOAD(handle);
238-
RETURN_FALSE;
231+
return FAILURE;
239232
}
240233

241234
if ((type == MODULE_TEMPORARY || start_now) && module_entry->request_startup_func) {
242235
if (module_entry->request_startup_func(type, module_entry->module_number TSRMLS_CC) == FAILURE) {
243236
php_error_docref(NULL TSRMLS_CC, error_type, "Unable to initialize module '%s'", module_entry->name);
244237
DL_UNLOAD(handle);
245-
RETURN_FALSE;
238+
return FAILURE;
246239
}
247240
}
248-
RETURN_TRUE;
241+
return SUCCESS;
242+
}
243+
/* }}} */
244+
245+
/* {{{ php_dl
246+
*/
247+
PHPAPI void php_dl(zval *file, int type, zval *return_value, int start_now TSRMLS_DC)
248+
{
249+
char *filename;
250+
251+
filename = Z_STRVAL_P(file);
252+
253+
/* Load extension */
254+
if (php_load_extension(filename, type, start_now TSRMLS_CC) == FAILURE) {
255+
RETVAL_FALSE;
256+
} else {
257+
RETVAL_TRUE;
258+
}
249259
}
250260
/* }}} */
251261

@@ -256,7 +266,7 @@ PHP_MINFO_FUNCTION(dl)
256266

257267
#else
258268

259-
void php_dl(zval *file, int type, zval *return_value, int start_now TSRMLS_DC)
269+
PHPAPI void php_dl(zval *file, int type, zval *return_value, int start_now TSRMLS_DC)
260270
{
261271
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot dynamically load %s - dynamic modules are not supported", Z_STRVAL_P(file));
262272
RETURN_FALSE;

ext/standard/dl.h

+1
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#ifndef DL_H
2424
#define DL_H
2525

26+
PHPAPI int php_load_extension(char *filename, int type, int start_now TSRMLS_DC);
2627
PHPAPI void php_dl(zval *file,int type, zval *return_value, int start_now TSRMLS_DC);
2728

2829
/* dynamic loading functions */

main/php_ini.c

+34-23
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ typedef struct _php_extension_lists {
4747
} php_extension_lists;
4848

4949
/* True globals */
50+
static int is_special_section = 0;
5051
static HashTable *active_ini_hash;
5152
static HashTable configuration_hash;
5253
PHPAPI char *php_ini_opened_path=NULL;
@@ -148,6 +149,7 @@ PHPAPI void display_ini_entries(zend_module_entry *module)
148149
/* }}} */
149150

150151
/* php.ini support */
152+
#define PHP_EXTENSION_TOKEN "extension"
151153
#ifdef ZTS
152154
# if (ZEND_DEBUG)
153155
# define ZEND_EXTENSION_TOKEN "zend_extension_debug_ts"
@@ -185,6 +187,7 @@ static void php_ini_parser_cb(zval *arg1, zval *arg2, zval *arg3, int callback_t
185187
{
186188
zval *entry;
187189
HashTable *active_hash;
190+
char *extension_name;
188191

189192
if (active_ini_hash) {
190193
active_hash = active_ini_hash;
@@ -199,19 +202,12 @@ static void php_ini_parser_cb(zval *arg1, zval *arg2, zval *arg3, int callback_t
199202
break;
200203
}
201204

202-
/* FIXME: Should the extension loading be disabled for PATH sections? */
203-
204205
/* PHP and Zend extensions are not added into configuration hash! */
205-
if (!strcasecmp(Z_STRVAL_P(arg1), "extension")) { /* load function module */
206-
zval copy;
207-
208-
copy = *arg2;
209-
zval_copy_ctor(&copy);
210-
Z_SET_REFCOUNT(copy, 0);
211-
zend_llist_add_element(&extension_lists.functions, &copy);
212-
} else if (!strcasecmp(Z_STRVAL_P(arg1), ZEND_EXTENSION_TOKEN)) { /* load Zend extension */
213-
char *extension_name = estrndup(Z_STRVAL_P(arg2), Z_STRLEN_P(arg2));
214-
206+
if (!is_special_section && !strcasecmp(Z_STRVAL_P(arg1), PHP_EXTENSION_TOKEN)) { /* load PHP extension */
207+
extension_name = estrndup(Z_STRVAL_P(arg2), Z_STRLEN_P(arg2));
208+
zend_llist_add_element(&extension_lists.functions, &extension_name);
209+
} else if (!is_special_section && !strcasecmp(Z_STRVAL_P(arg1), ZEND_EXTENSION_TOKEN)) { /* load Zend extension */
210+
extension_name = estrndup(Z_STRVAL_P(arg2), Z_STRLEN_P(arg2));
215211
zend_llist_add_element(&extension_lists.engine, &extension_name);
216212

217213
/* All other entries are added into either configuration_hash or active ini section array */
@@ -262,18 +258,21 @@ static void php_ini_parser_cb(zval *arg1, zval *arg2, zval *arg3, int callback_t
262258
char *key = NULL;
263259
uint key_len;
264260

265-
/* Only PATH sections are handled here! */
261+
/* PATH sections */
266262
if (!strncasecmp(Z_STRVAL_P(arg1), "PATH", sizeof("PATH") - 1)) {
267263
key = Z_STRVAL_P(arg1);
268264
key = key + sizeof("PATH") - 1;
269265
key_len = Z_STRLEN_P(arg1) - sizeof("PATH") + 1;
266+
is_special_section = 1;
270267

271-
#if 0 /* Disable HOST sections for now. If someone can come up with some good usage case, then I can reconsider :) */
268+
/* HOST sections */
272269
} else if (!strncasecmp(Z_STRVAL_P(arg1), "HOST", sizeof("HOST") - 1)) {
273270
key = Z_STRVAL_P(arg1);
274271
key = key + sizeof("HOST") - 1;
275272
key_len = Z_STRLEN_P(arg1) - sizeof("HOST") + 1;
276-
#endif
273+
is_special_section = 1;
274+
} else {
275+
is_special_section = 0;
277276
}
278277

279278
if (key && key_len > 0) {
@@ -313,14 +312,11 @@ static void php_ini_parser_cb(zval *arg1, zval *arg2, zval *arg3, int callback_t
313312
}
314313
/* }}} */
315314

316-
/* {{{ php_load_function_extension_cb
315+
/* {{{ php_load_php_extension_cb
317316
*/
318-
static void php_load_function_extension_cb(void *arg TSRMLS_DC)
317+
static void php_load_php_extension_cb(void *arg TSRMLS_DC)
319318
{
320-
zval *extension = (zval *) arg;
321-
zval zval;
322-
323-
php_dl(extension, MODULE_PERSISTENT, &zval, 0 TSRMLS_CC);
319+
php_load_extension(*((char **) arg), MODULE_PERSISTENT, 0 TSRMLS_CC);
324320
}
325321
/* }}} */
326322

@@ -352,7 +348,7 @@ int php_init_config(TSRMLS_D)
352348
}
353349

354350
zend_llist_init(&extension_lists.engine, sizeof(char *), (llist_dtor_func_t) free_estring, 1);
355-
zend_llist_init(&extension_lists.functions, sizeof(zval), (llist_dtor_func_t) ZVAL_DESTRUCTOR, 1);
351+
zend_llist_init(&extension_lists.functions, sizeof(zval), (llist_dtor_func_t) free_estring, 1);
356352

357353
safe_mode_state = PG(safe_mode);
358354
open_basedir = PG(open_basedir);
@@ -682,7 +678,7 @@ int php_shutdown_config(void)
682678
void php_ini_register_extensions(TSRMLS_D)
683679
{
684680
zend_llist_apply(&extension_lists.engine, php_load_zend_extension_cb TSRMLS_CC);
685-
zend_llist_apply(&extension_lists.functions, php_load_function_extension_cb TSRMLS_CC);
681+
zend_llist_apply(&extension_lists.functions, php_load_php_extension_cb TSRMLS_CC);
686682

687683
zend_llist_destroy(&extension_lists.engine);
688684
zend_llist_destroy(&extension_lists.functions);
@@ -764,6 +760,21 @@ PHPAPI void php_ini_activate_per_dir_config(char *path, uint path_len TSRMLS_DC)
764760
}
765761
/* }}} */
766762

763+
/* {{{ php_ini_activate_per_host_config
764+
*/
765+
PHPAPI void php_ini_activate_per_host_config(char *host, uint host_len TSRMLS_DC)
766+
{
767+
zval *tmp;
768+
769+
if (host && host_len) {
770+
/* Search for source array matching the host from configuration_hash */
771+
if (zend_hash_find(&configuration_hash, host, host_len, (void **) &tmp) == SUCCESS) {
772+
php_ini_activate_config(Z_ARRVAL_P(tmp), PHP_INI_SYSTEM, PHP_INI_STAGE_ACTIVATE TSRMLS_CC);
773+
}
774+
}
775+
}
776+
/* }}} */
777+
767778
/* {{{ cfg_get_entry
768779
*/
769780
PHPAPI zval *cfg_get_entry(char *name, uint name_length)

main/php_ini.h

+1
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ PHPAPI int cfg_get_string(char *varname, char **result);
3535
PHPAPI int php_parse_user_ini_file(char *dirname, char *ini_filename, HashTable *target_hash TSRMLS_DC);
3636
PHPAPI void php_ini_activate_config(HashTable *source_hash, int modify_type, int stage TSRMLS_DC);
3737
PHPAPI void php_ini_activate_per_dir_config(char *path, uint path_len TSRMLS_DC);
38+
PHPAPI void php_ini_activate_per_host_config(char *host, uint host_len TSRMLS_DC);
3839
#if ZEND_DEBUG
3940
PHPAPI HashTable get_configuration_hash(void);
4041
#endif

sapi/cgi/cgi_main.c

+7-3
Original file line numberDiff line numberDiff line change
@@ -702,7 +702,7 @@ static void php_cgi_ini_activate_user_config(char *path, int path_len, int start
702702

703703
static int sapi_cgi_activate(TSRMLS_D)
704704
{
705-
char *path, *doc_root;
705+
char *path, *doc_root, *server_name;
706706
uint path_len, doc_root_len;
707707

708708
/* PATH_TRANSLATED should be defined at this stage but better safe than sorry :) */
@@ -711,9 +711,10 @@ static int sapi_cgi_activate(TSRMLS_D)
711711
}
712712

713713
doc_root = sapi_cgibin_getenv("DOCUMENT_ROOT", sizeof("DOCUMENT_ROOT") - 1 TSRMLS_CC);
714+
server_name = sapi_cgibin_getenv("SERVER_NAME", sizeof("SERVER_NAME") - 1 TSRMLS_CC);
714715

715-
/* DOCUMENT_ROOT should also be defined at this stage..but better check it anyway */
716-
if (!doc_root) {
716+
/* DOCUMENT_ROOT and SERVER_NAME should also be defined at this stage..but better check it anyway */
717+
if (!doc_root || !server_name) {
717718
return FAILURE;
718719
}
719720
doc_root_len = strlen(doc_root);
@@ -736,6 +737,9 @@ static int sapi_cgi_activate(TSRMLS_D)
736737
/* Activate per-dir-system-configuration defined in php.ini and stored into configuration_hash during startup */
737738
php_ini_activate_per_dir_config(path, path_len TSRMLS_CC); /* Note: for global settings sake we check from root to path */
738739

740+
/* Activate per-host-system-configuration defined in php.ini and stored into configuration_hash during startup */
741+
php_ini_activate_per_host_config(server_name, strlen(server_name) + 1 TSRMLS_CC);
742+
739743
/* Load and activate user ini files in path starting from DOCUMENT_ROOT */
740744
if (strlen(PG(user_ini_filename))) {
741745
php_cgi_ini_activate_user_config(path, path_len, doc_root_len - 1 TSRMLS_CC);

0 commit comments

Comments
 (0)