diff --git a/phpBB/common.php b/phpBB/common.php index 4ce3ba8a640..616be921181 100644 --- a/phpBB/common.php +++ b/phpBB/common.php @@ -51,20 +51,10 @@ $server_port = 443; } - $script_name = (!empty($_SERVER['REQUEST_URI'])) ? $_SERVER['REQUEST_URI'] : getenv('REQUEST_URI'); - if (!$script_name) - { - $script_name = (!empty($_SERVER['PHP_SELF'])) ? $_SERVER['PHP_SELF'] : getenv('PHP_SELF'); - } - - // $phpbb_root_path accounts for redirects from e.g. /adm - $script_path = trim(dirname($script_name)) . '/' . $phpbb_root_path . 'install/app.' . $phpEx; - // Replace any number of consecutive backslashes and/or slashes with a single slash - // (could happen on some proxy setups and/or Windows servers) - $script_path = preg_replace('#[\\\\/]{2,}#', '/', $script_path); + $script_path = phpbb_get_install_redirect($phpbb_root_path, $phpEx); // Eliminate . and .. from the path - require($phpbb_root_path . 'phpbb/filesystem.' . $phpEx); + require($phpbb_root_path . 'phpbb/filesystem/filesystem.' . $phpEx); $phpbb_filesystem = new phpbb\filesystem\filesystem(); $script_path = $phpbb_filesystem->clean_path($script_path); diff --git a/phpBB/includes/functions.php b/phpBB/includes/functions.php index 7353fa2132e..17b3eda34e4 100644 --- a/phpBB/includes/functions.php +++ b/phpBB/includes/functions.php @@ -1814,6 +1814,31 @@ function redirect($url, $return = false, $disable_cd_check = false) exit; } +/** + * Returns the install redirect path for phpBB. + * + * @param string $phpbb_root_path The root path of the phpBB installation. + * @param string $phpEx The file extension of php files, e.g., "php". + * @return string The install redirect path. + */ +function phpbb_get_install_redirect(string $phpbb_root_path, string $phpEx): string +{ + $script_name = (!empty($_SERVER['REQUEST_URI'])) ? $_SERVER['REQUEST_URI'] : getenv('REQUEST_URI'); + if (!$script_name) + { + $script_name = (!empty($_SERVER['PHP_SELF'])) ? $_SERVER['PHP_SELF'] : getenv('PHP_SELF'); + } + + // Add trailing dot to prevent dirname() from returning parent directory if $script_name is a directory + $script_name = substr($script_name, -1) === '/' ? $script_name . '.' : $script_name; + + // $phpbb_root_path accounts for redirects from e.g. /adm + $script_path = trim(dirname($script_name)) . '/' . $phpbb_root_path . 'install/app.' . $phpEx; + // Replace any number of consecutive backslashes and/or slashes with a single slash + // (could happen on some proxy setups and/or Windows servers) + return preg_replace('#[\\\\/]{2,}#', '/', $script_path); +} + /** * Re-Apply session id after page reloads */ diff --git a/tests/functions/phpbb_get_install_redirect_test.php b/tests/functions/phpbb_get_install_redirect_test.php new file mode 100644 index 00000000000..22b9ade5895 --- /dev/null +++ b/tests/functions/phpbb_get_install_redirect_test.php @@ -0,0 +1,68 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +class phpbb_get_install_redirect_test extends phpbb_test_case +{ + public function data_redirect(): array + { + return [ + [ + ['REQUEST_URI' => '/foo/bar/'], + '/foo/bar/install/app.php', + ], + [ + ['REQUEST_URI' => '/foo/bar/index.php'], + '/foo/bar/install/app.php', + ], + [ + ['REQUEST_URI' => '/foo/bar'], + '/foo/install/app.php', + ], + [ + ['REQUEST_URI' => '/foo/'], + '/foo/install/app.php', + ], + [ + ['REQUEST_URI' => '/foo/index.php'], + '/foo/install/app.php', + ], + [ + [ + 'REQUEST_URI' => '/foo/bar/', + 'PHP_SELF' => '/foo/bar/index.php' + ], + '/foo/bar/install/app.php', + ], + [ + [ + 'REQUEST_URI' => '', + 'PHP_SELF' => '/foo/bar/index.php' + ], + '/foo/bar/install/app.php', + ], + ]; + } + + /** + * @backupGlobals enabled + * @dataProvider data_redirect + */ + public function test_install_redirect($server_vars, $expected) + { + $phpbb_root_path = '/'; + $phpEx = 'php'; + + $_SERVER = array_merge($_SERVER, $server_vars); + $this->assertEquals($expected, phpbb_get_install_redirect($phpbb_root_path, $phpEx)); + } +}