diff --git a/sapi/fpm/fpm/fpm_main.c b/sapi/fpm/fpm/fpm_main.c index 57006a15c7a08..b05114e68216f 100644 --- a/sapi/fpm/fpm/fpm_main.c +++ b/sapi/fpm/fpm/fpm_main.c @@ -1103,6 +1103,7 @@ static void init_request_info(void) script_path_translated = __unixify(script_path_translated, 0, NULL, 1, 0); #endif + /* * if the file doesn't exist, try to extract PATH_INFO out * of it by stat'ing back through the '/' @@ -1118,8 +1119,19 @@ static void init_request_info(void) char *ptr; if (pt) { + // If DocumentRoot contains special characters like '%' or cyrillic 'рф' and PHP is invoked with SetHandler (not applicable to ProxyPassMatch), + // then the special characters are urlencoded by apache, and we need to decode them, for example with + // DocumentRoot /home/hans/web/cyrillicрф.ratma.net/public_html/test%lol + // env_script_filename contains /home/hans/web/cyrillic%D1%80%D1%84.ratma.net/public_html/test%25lol/index.php. + // and we must decode it to /home/hans/web/cyrillicрф.ratma.net/public_html/test%lol/index.php. + if(apache_was_here && memchr(pt, '%', len)) { + len = php_raw_url_decode(pt, len); + ptr = &pt[len]; // php_raw_url_decode() writes a trailing null byte, &pt[len] is that null byte. + goto apache_special_jump; + } while ((ptr = strrchr(pt, '/')) || (ptr = strrchr(pt, '\\'))) { *ptr = 0; + apache_special_jump: if (stat(pt, &st) == 0 && S_ISREG(st.st_mode)) { /* * okay, we found the base script!