mirror of
https://github.com/phpbb/phpbb.git
synced 2025-08-11 19:24:01 +02:00
Merge remote-tracking branch 'Marc/ticket/11997' into develop
* Marc/ticket/11997: (23 commits) [ticket/11997] Use functional test cases that should always work [ticket/11997] Fix redirect tests for mod rewrite [ticket/11997] Add user's page dir to redirect path and fix unit tests for it [ticket/11997] Remove obsolete function get_controller_redirect_url() [ticket/11997] Use path_helper in in foo/bar extension for redirect URLs [ticket/11997] Add remove_web_root_path() in order to prevent incorrect URLs [ticket/11997] Do not check if file or dir we redirect to exist [ticket/11997] Modifiy tests after adding path_helper clean_url method [ticket/11997] Add clean_url() method to path_helper [ticket/11997] Allow redirects to parent folders like previously [ticket/11997] Move expected redirect returns to controller and output to HTML [ticket/11997] Fix tests for path_helper's get_controller_redirect_url() [ticket/11997] Use get_controller_redirect_url() in redirect() function [ticket/11997] Add method for controller redirect URLs to path helper [ticket/11997] Undo changes to phpbb_own_realpath() [ticket/11997] Remove obsolete failover_flag in function redirect() [ticket/11997] Add functional test for redirects in controller [ticket/11997] Fix missing global [ticket/11997] Fix redirects from inside controllers [ticket/11997] Use $phpbb_filesystem->clean_path() for proper redirect paths ...
This commit is contained in:
@@ -2434,7 +2434,7 @@ function generate_board_url($without_script_path = false)
|
||||
*/
|
||||
function redirect($url, $return = false, $disable_cd_check = false)
|
||||
{
|
||||
global $db, $cache, $config, $user, $phpbb_root_path;
|
||||
global $db, $cache, $config, $user, $phpbb_root_path, $phpbb_filesystem, $phpbb_path_helper, $phpEx;
|
||||
|
||||
$failover_flag = false;
|
||||
|
||||
@@ -2477,78 +2477,34 @@ function redirect($url, $return = false, $disable_cd_check = false)
|
||||
// Relative uri
|
||||
$pathinfo = pathinfo($url);
|
||||
|
||||
if (!$disable_cd_check && !file_exists($pathinfo['dirname'] . '/'))
|
||||
// Is the uri pointing to the current directory?
|
||||
if ($pathinfo['dirname'] == '.')
|
||||
{
|
||||
$url = str_replace('../', '', $url);
|
||||
$pathinfo = pathinfo($url);
|
||||
$url = str_replace('./', '', $url);
|
||||
|
||||
if (!file_exists($pathinfo['dirname'] . '/'))
|
||||
// Strip / from the beginning
|
||||
if ($url && substr($url, 0, 1) == '/')
|
||||
{
|
||||
// fallback to "last known user page"
|
||||
// at least this way we know the user does not leave the phpBB root
|
||||
$url = generate_board_url() . '/' . $user->page['page'];
|
||||
$failover_flag = true;
|
||||
$url = substr($url, 1);
|
||||
}
|
||||
}
|
||||
|
||||
if (!$failover_flag)
|
||||
$url = $phpbb_path_helper->remove_web_root_path($url);
|
||||
|
||||
if ($user->page['page_dir'])
|
||||
{
|
||||
// Is the uri pointing to the current directory?
|
||||
if ($pathinfo['dirname'] == '.')
|
||||
{
|
||||
$url = str_replace('./', '', $url);
|
||||
|
||||
// Strip / from the beginning
|
||||
if ($url && substr($url, 0, 1) == '/')
|
||||
{
|
||||
$url = substr($url, 1);
|
||||
}
|
||||
|
||||
if ($user->page['page_dir'])
|
||||
{
|
||||
$url = generate_board_url() . '/' . $user->page['page_dir'] . '/' . $url;
|
||||
}
|
||||
else
|
||||
{
|
||||
$url = generate_board_url() . '/' . $url;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Used ./ before, but $phpbb_root_path is working better with urls within another root path
|
||||
$root_dirs = explode('/', str_replace('\\', '/', phpbb_realpath($phpbb_root_path)));
|
||||
$page_dirs = explode('/', str_replace('\\', '/', phpbb_realpath($pathinfo['dirname'])));
|
||||
$intersection = array_intersect_assoc($root_dirs, $page_dirs);
|
||||
|
||||
$root_dirs = array_diff_assoc($root_dirs, $intersection);
|
||||
$page_dirs = array_diff_assoc($page_dirs, $intersection);
|
||||
|
||||
$dir = str_repeat('../', sizeof($root_dirs)) . implode('/', $page_dirs);
|
||||
|
||||
// Strip / from the end
|
||||
if ($dir && substr($dir, -1, 1) == '/')
|
||||
{
|
||||
$dir = substr($dir, 0, -1);
|
||||
}
|
||||
|
||||
// Strip / from the beginning
|
||||
if ($dir && substr($dir, 0, 1) == '/')
|
||||
{
|
||||
$dir = substr($dir, 1);
|
||||
}
|
||||
|
||||
$url = str_replace($pathinfo['dirname'] . '/', '', $url);
|
||||
|
||||
// Strip / from the beginning
|
||||
if (substr($url, 0, 1) == '/')
|
||||
{
|
||||
$url = substr($url, 1);
|
||||
}
|
||||
|
||||
$url = (!empty($dir) ? $dir . '/' : '') . $url;
|
||||
$url = generate_board_url() . '/' . $url;
|
||||
}
|
||||
$url = $user->page['page_dir'] . '/' . $url;
|
||||
}
|
||||
|
||||
$url = generate_board_url() . '/' . $url;
|
||||
}
|
||||
|
||||
// Clean URL and check if we go outside the forum directory
|
||||
$url = $phpbb_path_helper->clean_url($url);
|
||||
|
||||
if (!$disable_cd_check && strpos($url, generate_board_url(true)) === false)
|
||||
{
|
||||
trigger_error('INSECURE_REDIRECT', E_USER_ERROR);
|
||||
}
|
||||
|
||||
// Make sure no linebreaks are there... to prevent http response splitting for PHP < 4.4.2
|
||||
|
@@ -101,6 +101,27 @@ class path_helper
|
||||
return $path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Strips away the web root path and prepends the normal root path
|
||||
*
|
||||
* This replaces get_web_root_path() . some_url with
|
||||
* $phpbb_root_path . some_url
|
||||
*
|
||||
* @param string $path The path to be updated
|
||||
* @return string
|
||||
*/
|
||||
public function remove_web_root_path($path)
|
||||
{
|
||||
if (strpos($path, $this->get_web_root_path()) === 0)
|
||||
{
|
||||
$path = substr($path, strlen($this->get_web_root_path()));
|
||||
|
||||
return $this->phpbb_root_path . $path;
|
||||
}
|
||||
|
||||
return $path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a relative root path from the current URL
|
||||
*
|
||||
@@ -162,4 +183,27 @@ class path_helper
|
||||
*/
|
||||
return $this->web_root_path = $this->phpbb_root_path . str_repeat('../', $corrections - 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Eliminates useless . and .. components from specified URL
|
||||
*
|
||||
* @param string $url URL to clean
|
||||
*
|
||||
* @return string Cleaned URL
|
||||
*/
|
||||
public function clean_url($url)
|
||||
{
|
||||
$delimiter_position = strpos($url, '://');
|
||||
// URL should contain :// but it shouldn't start with it.
|
||||
// Do not clean URLs that do not fit these constraints.
|
||||
if (empty($delimiter_position))
|
||||
{
|
||||
return $url;
|
||||
}
|
||||
$scheme = substr($url, 0, $delimiter_position) . '://';
|
||||
// Add length of URL delimiter to position
|
||||
$path = substr($url, $delimiter_position + 3);
|
||||
|
||||
return $scheme . $this->filesystem->clean_path($path);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user