]> granicus.if.org Git - php/commitdiff
- Allow using full path to load modules using "extension" directive
authorJani Taskinen <jani@php.net>
Fri, 9 Nov 2007 16:26:55 +0000 (16:26 +0000)
committerJani Taskinen <jani@php.net>
Fri, 9 Nov 2007 16:26:55 +0000 (16:26 +0000)
ext/standard/dl.c
ext/standard/dl.h
main/php_ini.c

index 09a757af4c288281b7d6082533c978fc8b9f86c3..623aea9d33da3a0b41d265fe25c559dec24b5561 100644 (file)
@@ -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;
index eda621099d5de9c6b5b4659a7263537502ebbdb4..ffd595271a6abe5c2c07d0d7878eedc1b6589c82 100644 (file)
@@ -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);
index 882b83f9b60b9ac5bd89b7ae0e39728d5d8fb86b..7b0ec241e7f25a5d67d9d839b18357ba7d7a6045 100644 (file)
@@ -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(&copy);
-                                       Z_SET_REFCOUNT(copy, 0);
-                                       zend_llist_add_element(&extension_lists.functions, &copy);
-                               } 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);