From: Jani Taskinen Date: Fri, 9 Nov 2007 16:26:55 +0000 (+0000) Subject: - Allow using full path to load modules using "extension" directive X-Git-Tag: RELEASE_2_0_0a1~1400 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=ad9605a722f0085330c4545ae28b7e9b4ed170ab;p=php - Allow using full path to load modules using "extension" directive --- diff --git a/ext/standard/dl.c b/ext/standard/dl.c index 09a757af4c..623aea9d33 100644 --- a/ext/standard/dl.c +++ b/ext/standard/dl.c @@ -80,7 +80,7 @@ PHP_FUNCTION(dl) /* {{{ php_dl */ -void php_dl(zval *file, int type, zval *return_value, int start_now TSRMLS_DC) +PHPAPI int php_load_extension(char *filename, int type, int start_now TSRMLS_DC) /* {{{ */ { void *handle; char *libpath; @@ -88,8 +88,6 @@ void php_dl(zval *file, int type, zval *return_value, int start_now TSRMLS_DC) zend_module_entry *(*get_module)(void); int error_type; char *extension_dir; - char *filename; - int filename_len; if (type == MODULE_PERSISTENT) { extension_dir = INI_STR("extension_dir"); @@ -103,24 +101,16 @@ void php_dl(zval *file, int type, zval *return_value, int start_now TSRMLS_DC) error_type = E_CORE_WARNING; } - if (Z_TYPE_P(file) == IS_UNICODE) { - if (FAILURE == php_stream_path_encode(NULL, &filename, &filename_len, Z_USTRVAL_P(file), Z_USTRLEN_P(file), REPORT_ERRORS, FG(default_context))) { - return; - } - } else { - filename = Z_STRVAL_P(file); - filename_len = Z_STRLEN_P(file); - } - - if (extension_dir && extension_dir[0]){ - int extension_dir_len = strlen(extension_dir); - + /* Check if passed filename contains directory separators */ + if (strchr(filename, '/') != NULL || strchr(filename, DEFAULT_SLASH) != NULL) { + /* Passing modules with full path is not supported for dynamically loaded extensions */ if (type == MODULE_TEMPORARY) { - if (strchr(filename, '/') != NULL || strchr(filename, DEFAULT_SLASH) != NULL) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Temporary module name should contain only filename"); - RETURN_FALSE; - } + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Temporary module name should contain only filename"); + return FAILURE; } + libpath = estrdup(filename); + } else if (extension_dir && extension_dir[0]) { + int extension_dir_len = strlen(extension_dir); if (IS_SLASH(extension_dir[extension_dir_len-1])) { spprintf(&libpath, 0, "%s%s", extension_dir, filename); /* SAFE */ @@ -128,11 +118,7 @@ void php_dl(zval *file, int type, zval *return_value, int start_now TSRMLS_DC) spprintf(&libpath, 0, "%s%c%s", extension_dir, DEFAULT_SLASH, filename); /* SAFE */ } } else { - libpath = estrndup(filename, filename_len); - } - - if (Z_TYPE_P(file) == IS_UNICODE) { - efree(filename); + return FAILURE; /* Not full path given or extension_dir is not set */ } /* load dynamic symbol */ @@ -141,9 +127,8 @@ void php_dl(zval *file, int type, zval *return_value, int start_now TSRMLS_DC) php_error_docref(NULL TSRMLS_CC, error_type, "Unable to load dynamic library '%s' - %s", libpath, GET_DL_ERROR()); GET_DL_ERROR(); /* free the buffer storing the error */ efree(libpath); - RETURN_FALSE; + return FAILURE; } - efree(libpath); get_module = (zend_module_entry *(*)(void)) DL_FETCH_SYMBOL(handle, "get_module"); @@ -158,8 +143,8 @@ void php_dl(zval *file, int type, zval *return_value, int start_now TSRMLS_DC) if (!get_module) { DL_UNLOAD(handle); - php_error_docref(NULL TSRMLS_CC, error_type, "Invalid library (maybe not a PHP library) '%R'", Z_TYPE_P(file), Z_UNIVAL_P(file)); - RETURN_FALSE; + php_error_docref(NULL TSRMLS_CC, error_type, "Invalid library (maybe not a PHP library) '%s'", filename); + return FAILURE; } module_entry = get_module(); if ((module_entry->zend_debug != ZEND_DEBUG) || @@ -213,7 +198,7 @@ void php_dl(zval *file, int type, zval *return_value, int start_now TSRMLS_DC) name, zend_api, zend_debug, zts, ZEND_MODULE_API_NO, ZEND_DEBUG, USING_ZTS); DL_UNLOAD(handle); - RETURN_FALSE; + return FAILURE; } module_entry->type = type; module_entry->module_number = zend_next_free_module(); @@ -221,22 +206,50 @@ void php_dl(zval *file, int type, zval *return_value, int start_now TSRMLS_DC) if ((module_entry = zend_register_module_ex(module_entry TSRMLS_CC)) == NULL) { DL_UNLOAD(handle); - RETURN_FALSE; + return FAILURE; } if ((type == MODULE_TEMPORARY || start_now) && zend_startup_module_ex(module_entry TSRMLS_CC) == FAILURE) { DL_UNLOAD(handle); - RETURN_FALSE; + return FAILURE; } if ((type == MODULE_TEMPORARY || start_now) && module_entry->request_startup_func) { if (module_entry->request_startup_func(type, module_entry->module_number TSRMLS_CC) == FAILURE) { php_error_docref(NULL TSRMLS_CC, error_type, "Unable to initialize module '%s'", module_entry->name); DL_UNLOAD(handle); - RETURN_FALSE; + return FAILURE; } } - RETURN_TRUE; + return SUCCESS; +} +/* }}} */ + +/* {{{ php_dl + */ +PHPAPI void php_dl(zval *file, int type, zval *return_value, int start_now TSRMLS_DC) +{ + char *filename; + int filename_len; + + if (Z_TYPE_P(file) == IS_UNICODE) { + if (FAILURE == php_stream_path_encode(NULL, &filename, &filename_len, Z_USTRVAL_P(file), Z_USTRLEN_P(file), REPORT_ERRORS, FG(default_context))) { + return; + } + } else { + filename = Z_STRVAL_P(file); + } + + /* Load extension */ + if (php_load_extension(filename, type, start_now TSRMLS_CC) == FAILURE) { + RETVAL_FALSE; + } else { + RETVAL_TRUE; + } + + if (Z_TYPE_P(file) == IS_UNICODE) { + efree(filename); + } } /* }}} */ @@ -247,7 +260,7 @@ PHP_MINFO_FUNCTION(dl) #else -void php_dl(zval *file, int type, zval *return_value, int start_now TSRMLS_DC) +PHPAPI void php_dl(zval *file, int type, zval *return_value, int start_now TSRMLS_DC) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot dynamically load %R - dynamic modules are not supported", Z_TYPE_P(file), Z_UNIVAL_P(file)); RETURN_FALSE; diff --git a/ext/standard/dl.h b/ext/standard/dl.h index eda621099d..ffd595271a 100644 --- a/ext/standard/dl.h +++ b/ext/standard/dl.h @@ -23,7 +23,8 @@ #ifndef DL_H #define DL_H -void php_dl(zval *file,int type, zval *return_value, int start_now TSRMLS_DC); +PHPAPI int php_load_extension(char *filename, int type, int start_now TSRMLS_DC); +PHPAPI void php_dl(zval *file,int type, zval *return_value, int start_now TSRMLS_DC); /* dynamic loading functions */ PHPAPI PHP_FUNCTION(dl); diff --git a/main/php_ini.c b/main/php_ini.c index 882b83f9b6..7b0ec241e7 100644 --- a/main/php_ini.c +++ b/main/php_ini.c @@ -47,6 +47,7 @@ typedef struct _php_extension_lists { } php_extension_lists; /* True globals */ +static int is_special_section = 0; static HashTable *active_ini_hash; static HashTable configuration_hash; PHPAPI char *php_ini_opened_path=NULL; @@ -148,6 +149,7 @@ PHPAPI void display_ini_entries(zend_module_entry *module) /* }}} */ /* php.ini support */ +#define PHP_EXTENSION_TOKEN "extension" #ifdef ZTS # if (ZEND_DEBUG) # 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 { zval *entry; HashTable *active_hash; + char *extension_name; if (active_ini_hash) { active_hash = active_ini_hash; @@ -199,19 +202,12 @@ static void php_ini_parser_cb(zval *arg1, zval *arg2, zval *arg3, int callback_t break; } -/* FIXME: Should the extension loading be disabled for PATH sections? */ - /* PHP and Zend extensions are not added into configuration hash! */ - if (!strcasecmp(Z_STRVAL_P(arg1), "extension")) { /* load function module */ - zval copy; - - copy = *arg2; - zval_copy_ctor(©); - Z_SET_REFCOUNT(copy, 0); - zend_llist_add_element(&extension_lists.functions, ©); - } else if (!strcasecmp(Z_STRVAL_P(arg1), ZEND_EXTENSION_TOKEN)) { /* load Zend extension */ - char *extension_name = estrndup(Z_STRVAL_P(arg2), Z_STRLEN_P(arg2)); - + if (!is_special_section && !strcasecmp(Z_STRVAL_P(arg1), "extension")) { /* load function module */ + extension_name = estrndup(Z_STRVAL_P(arg2), Z_STRLEN_P(arg2)); + zend_llist_add_element(&extension_lists.functions, &extension_name); + } else if (!is_special_section && !strcasecmp(Z_STRVAL_P(arg1), ZEND_EXTENSION_TOKEN)) { /* load Zend extension */ + extension_name = estrndup(Z_STRVAL_P(arg2), Z_STRLEN_P(arg2)); zend_llist_add_element(&extension_lists.engine, &extension_name); /* 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 char *key = NULL; uint key_len; - /* Only PATH sections are handled here! */ + /* PATH sections */ if (!strncasecmp(Z_STRVAL_P(arg1), "PATH", sizeof("PATH") - 1)) { key = Z_STRVAL_P(arg1); key = key + sizeof("PATH") - 1; key_len = Z_STRLEN_P(arg1) - sizeof("PATH") + 1; + is_special_section = 1; -#if 0 /* Disable HOST sections for now. If someone can come up with some good usage case, then I can reconsider :) */ + /* HOST sections */ } else if (!strncasecmp(Z_STRVAL_P(arg1), "HOST", sizeof("HOST") - 1)) { key = Z_STRVAL_P(arg1); key = key + sizeof("HOST") - 1; key_len = Z_STRLEN_P(arg1) - sizeof("HOST") + 1; -#endif + is_special_section = 1; + } else { + is_special_section = 0; } if (key && key_len > 0) { @@ -313,14 +312,11 @@ static void php_ini_parser_cb(zval *arg1, zval *arg2, zval *arg3, int callback_t } /* }}} */ -/* {{{ php_load_function_extension_cb +/* {{{ php_load_php_extension_cb */ -static void php_load_function_extension_cb(void *arg TSRMLS_DC) +static void php_load_php_extension_cb(void *arg TSRMLS_DC) { - zval *extension = (zval *) arg; - zval zval; - - php_dl(extension, MODULE_PERSISTENT, &zval, 0 TSRMLS_CC); + php_load_extension(*((char **) arg), MODULE_PERSISTENT, 0 TSRMLS_CC); } /* }}} */ @@ -351,7 +347,7 @@ int php_init_config(TSRMLS_D) } zend_llist_init(&extension_lists.engine, sizeof(char *), (llist_dtor_func_t) free_estring, 1); - zend_llist_init(&extension_lists.functions, sizeof(zval), (llist_dtor_func_t) ZVAL_DESTRUCTOR, 1); + zend_llist_init(&extension_lists.functions, sizeof(zval), (llist_dtor_func_t) free_estring, 1); open_basedir = PG(open_basedir); @@ -678,7 +674,7 @@ int php_shutdown_config(void) void php_ini_register_extensions(TSRMLS_D) { zend_llist_apply(&extension_lists.engine, php_load_zend_extension_cb TSRMLS_CC); - zend_llist_apply(&extension_lists.functions, php_load_function_extension_cb TSRMLS_CC); + zend_llist_apply(&extension_lists.functions, php_load_php_extension_cb TSRMLS_CC); zend_llist_destroy(&extension_lists.engine); zend_llist_destroy(&extension_lists.functions);