From 50aef7ec83e11e79ed0e2b71b2d1520f1d4aaa66 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Wed, 8 Aug 2007 13:01:40 +0000 Subject: [PATCH] - Fixed bug #42198 (SCRIPT_NAME and PHP_SELF truncated when inside a userdir and using PATH_INFO). - Fixed bug #31892 (PHP_SELF incorrect without cgi.fix_pathinfo, but turning on screws up PATH_INFO). --- NEWS | 4 ++ sapi/cgi/cgi_main.c | 102 ++++++++++++++++++++++++++++++-------------- 2 files changed, 74 insertions(+), 32 deletions(-) diff --git a/NEWS b/NEWS index ef285fadbe..38ed700c8a 100644 --- a/NEWS +++ b/NEWS @@ -7,11 +7,15 @@ PHP NEWS - Fixed bug #42222 (possible buffer overflow in php_openssl_make_REQ). (Pierre) - Fixed bug #42208 (substr_replace() crashes when the same array is passed more than once). (crrodriguez at suse dot de, Ilia) +- Fixed bug #42198 (SCRIPT_NAME and PHP_SELF truncated when inside a userdir + and using PATH_INFO). (Dmitry) - Fixed bug #42195 (C++ compiler required always). (Jani) - Fixed bug #42082 (NodeList length zero should be empty). (Hannes) - Fixed bug #41973 (./configure --with-ldap=shared fails with LDFLAGS="-Wl,--as-needed"). (Nuno) - Fixed bug #36492 (Userfilters can leak buckets). (Sara) +- Fixed bug #31892 (PHP_SELF incorrect without cgi.fix_pathinfo, but turning + on screws up PATH_INFO). (Dmitry) 02 Aug 2007, PHP 5.2.4RC1 - Removed --enable-versioning configure option. (Jani) diff --git a/sapi/cgi/cgi_main.c b/sapi/cgi/cgi_main.c index bd7b1cfb20..6f1ea9c7cb 100644 --- a/sapi/cgi/cgi_main.c +++ b/sapi/cgi/cgi_main.c @@ -522,16 +522,29 @@ void cgi_php_import_environment_variables(zval *array_ptr TSRMLS_DC) static void sapi_cgi_register_variables(zval *track_vars_array TSRMLS_DC) { - unsigned int new_val_len; - char *val = SG(request_info).request_uri ? SG(request_info).request_uri : ""; + char *script_name = SG(request_info).request_uri; + unsigned int script_name_len = script_name ? strlen(script_name) : 0; + char *path_info = sapi_cgibin_getenv("PATH_INFO", sizeof("PATH_INFO")-1 TSRMLS_CC); + unsigned int path_info_len = path_info ? strlen(path_info) : 0; + unsigned int php_self_len = script_name_len + path_info_len; + char *php_self = emalloc(php_self_len + 1); + + if (script_name) { + memcpy(php_self, script_name, script_name_len + 1); + } + if (path_info) { + memcpy(php_self + script_name_len, path_info, path_info_len + 1); + } + /* In CGI mode, we consider the environment to be a part of the server * variables */ php_import_environment_variables(track_vars_array TSRMLS_CC); /* Build the special-case PHP_SELF variable for the CGI version */ - if (sapi_module.input_filter(PARSE_SERVER, "PHP_SELF", &val, strlen(val), &new_val_len TSRMLS_CC)) { - php_register_variable_safe("PHP_SELF", val, new_val_len, track_vars_array TSRMLS_CC); + if (sapi_module.input_filter(PARSE_SERVER, "PHP_SELF", &php_self, php_self_len, &php_self_len TSRMLS_CC)) { + php_register_variable_safe("PHP_SELF", php_self, php_self_len, track_vars_array TSRMLS_CC); } + efree(php_self); } static void sapi_cgi_log_message(char *message) @@ -830,7 +843,21 @@ static void init_request_info(TSRMLS_D) if (orig_path_info != path_info) { if (orig_path_info) { + char old; + _sapi_cgibin_putenv("ORIG_PATH_INFO", orig_path_info TSRMLS_CC); + old = path_info[0]; + path_info[0] = 0; + if (!orig_script_name || + strcmp(orig_script_name, env_path_info) != 0) { + if (orig_script_name) { + _sapi_cgibin_putenv("ORIG_SCRIPT_NAME", orig_script_name TSRMLS_CC); + } + SG(request_info).request_uri = _sapi_cgibin_putenv("SCRIPT_NAME", env_path_info TSRMLS_CC); + } else { + SG(request_info).request_uri = orig_script_name; + } + path_info[0] = old; } env_path_info = _sapi_cgibin_putenv("PATH_INFO", path_info TSRMLS_CC); } @@ -847,8 +874,7 @@ static void init_request_info(TSRMLS_D) SCRIPT_FILENAME minus SCRIPT_NAME */ - if (env_document_root) - { + if (env_document_root) { int l = strlen(env_document_root); int path_translated_len = 0; char *path_translated = NULL; @@ -860,10 +886,7 @@ static void init_request_info(TSRMLS_D) /* we have docroot, so we should have: * DOCUMENT_ROOT=/docroot * SCRIPT_FILENAME=/docroot/info.php - * - * SCRIPT_NAME is the portion of the path beyond docroot */ - env_script_name = pt + l; /* PATH_TRANSLATED = DOCUMENT_ROOT + PATH_INFO */ path_translated_len = l + (env_path_info ? strlen(env_path_info) : 0); @@ -913,38 +936,47 @@ static void init_request_info(TSRMLS_D) script_path_translated = _sapi_cgibin_putenv("SCRIPT_FILENAME", NULL TSRMLS_CC); SG(sapi_headers).http_response_code = 404; } - if (!orig_script_name || - strcmp(orig_script_name, env_script_name) != 0) { - if (orig_script_name) { - _sapi_cgibin_putenv("ORIG_SCRIPT_NAME", orig_script_name TSRMLS_CC); + if (!SG(request_info).request_uri) { + if (!orig_script_name || + strcmp(orig_script_name, env_script_name) != 0) { + if (orig_script_name) { + _sapi_cgibin_putenv("ORIG_SCRIPT_NAME", orig_script_name TSRMLS_CC); + } + SG(request_info).request_uri = _sapi_cgibin_putenv("SCRIPT_NAME", env_script_name TSRMLS_CC); + } else { + SG(request_info).request_uri = orig_script_name; } - SG(request_info).request_uri = _sapi_cgibin_putenv("SCRIPT_NAME", env_script_name TSRMLS_CC); - } else { - SG(request_info).request_uri = orig_script_name; - } + } if (pt) { efree(pt); } + /* some server configurations allow '..' to slip through in the + translated path. We'll just refuse to handle such a path. */ + if (script_path_translated && !strstr(script_path_translated, "..")) { + SG(request_info).path_translated = estrdup(script_path_translated); + } } else { if (real_path) { script_path_translated = real_path; } /* make sure path_info/translated are empty */ if (!orig_script_filename || - (script_path_translated != orig_script_filename) || - strcmp(script_path_translated, orig_script_filename) != 0) { + (script_path_translated != orig_script_filename && + strcmp(script_path_translated, orig_script_filename) != 0)) { if (orig_script_filename) { _sapi_cgibin_putenv("ORIG_SCRIPT_FILENAME", orig_script_filename TSRMLS_CC); } script_path_translated = _sapi_cgibin_putenv("SCRIPT_FILENAME", script_path_translated TSRMLS_CC); } - if (orig_path_info) { - _sapi_cgibin_putenv("ORIG_PATH_INFO", orig_path_info TSRMLS_CC); - _sapi_cgibin_putenv("PATH_INFO", NULL TSRMLS_CC); - } - if (orig_path_translated) { - _sapi_cgibin_putenv("ORIG_PATH_TRANSLATED", orig_path_translated TSRMLS_CC); - _sapi_cgibin_putenv("PATH_TRANSLATED", NULL TSRMLS_CC); + if (env_redirect_url) { + if (orig_path_info) { + _sapi_cgibin_putenv("ORIG_PATH_INFO", orig_path_info TSRMLS_CC); + _sapi_cgibin_putenv("PATH_INFO", NULL TSRMLS_CC); + } + if (orig_path_translated) { + _sapi_cgibin_putenv("ORIG_PATH_TRANSLATED", orig_path_translated TSRMLS_CC); + _sapi_cgibin_putenv("PATH_TRANSLATED", NULL TSRMLS_CC); + } } if (env_script_name != orig_script_name) { if (orig_script_name) { @@ -954,6 +986,11 @@ static void init_request_info(TSRMLS_D) } else { SG(request_info).request_uri = env_script_name; } + /* some server configurations allow '..' to slip through in the + translated path. We'll just refuse to handle such a path. */ + if (script_path_translated && !strstr(script_path_translated, "..")) { + SG(request_info).path_translated = estrdup(script_path_translated); + } if (real_path) { free(real_path); } @@ -967,20 +1004,21 @@ static void init_request_info(TSRMLS_D) SG(request_info).request_uri = env_script_name; } #if !DISCARD_PATH - if (env_path_translated) + if (env_path_translated) { script_path_translated = env_path_translated; + } #endif + /* some server configurations allow '..' to slip through in the + translated path. We'll just refuse to handle such a path. */ + if (script_path_translated && !strstr(script_path_translated, "..")) { + SG(request_info).path_translated = estrdup(script_path_translated); + } #if ENABLE_PATHINFO_CHECK } #endif SG(request_info).request_method = sapi_cgibin_getenv("REQUEST_METHOD", sizeof("REQUEST_METHOD")-1 TSRMLS_CC); /* FIXME - Work out proto_num here */ SG(request_info).query_string = sapi_cgibin_getenv("QUERY_STRING", sizeof("QUERY_STRING")-1 TSRMLS_CC); - /* some server configurations allow '..' to slip through in the - translated path. We'll just refuse to handle such a path. */ - if (script_path_translated && !strstr(script_path_translated, "..")) { - SG(request_info).path_translated = estrdup(script_path_translated); - } SG(request_info).content_type = (content_type ? content_type : "" ); SG(request_info).content_length = (content_length ? atoi(content_length) : 0); -- 2.40.0