diff options
| -rw-r--r-- | phpBB/common.php | 5 | ||||
| -rw-r--r-- | phpBB/config/services.yml | 8 | ||||
| -rw-r--r-- | phpBB/includes/functions.php | 129 | ||||
| -rw-r--r-- | phpBB/phpbb/filesystem.php | 117 | ||||
| -rw-r--r-- | phpBB/phpbb/symfony_request.php | 46 | ||||
| -rw-r--r-- | tests/dbal/migrator_test.php | 2 | ||||
| -rw-r--r-- | tests/extension/manager_test.php | 2 | ||||
| -rw-r--r-- | tests/extension/metadata_manager_test.php | 2 | ||||
| -rw-r--r-- | tests/filesystem/clean_path_test.php | 7 | ||||
| -rw-r--r-- | tests/filesystem/web_root_path_test.php | 133 | ||||
| -rw-r--r-- | tests/log/function_view_log_test.php | 4 | ||||
| -rw-r--r-- | tests/mock/extension_manager.php | 2 | ||||
| -rw-r--r-- | tests/test_framework/phpbb_functional_test_case.php | 2 | 
13 files changed, 346 insertions, 113 deletions
diff --git a/phpBB/common.php b/phpBB/common.php index a7b7db28ac..43beb86972 100644 --- a/phpBB/common.php +++ b/phpBB/common.php @@ -47,7 +47,7 @@ if (!defined('PHPBB_INSTALLED'))  	// Eliminate . and .. from the path  	require($phpbb_root_path . 'phpbb/filesystem.' . $phpEx); -	$phpbb_filesystem = new phpbb_filesystem(); +	$phpbb_filesystem = new phpbb_filesystem($phpbb_root_path);  	$script_path = $phpbb_filesystem->clean_path($script_path);  	$url = (($secure) ? 'https://' : 'http://') . $server_name; @@ -110,7 +110,8 @@ $db			= $phpbb_container->get('dbal.conn');  request_var('', 0, false, false, $request); // "dependency injection" for a function  // Create a Symfony Request object from our phpbb_request object -$symfony_request = phpbb_create_symfony_request($request); +$symfony_request = $phpbb_container->get('symfony_request'); +$phpbb_filesystem = $phpbb_container->get('filesystem');  // Grab global variables, re-cache if necessary  $config = $phpbb_container->get('config'); diff --git a/phpBB/config/services.yml b/phpBB/config/services.yml index ba3b2a407d..a9c819fe9a 100644 --- a/phpBB/config/services.yml +++ b/phpBB/config/services.yml @@ -169,6 +169,9 @@ services:      filesystem:          class: phpbb_filesystem +        arguments: +            - @symfony_request +            - %core.root_path%      groupposition.legend:          class: phpbb_groupposition_legend @@ -252,6 +255,11 @@ services:      request:          class: phpbb_request +    symfony_request: +        class: phpbb_symfony_request +        arguments: +            - @request +      template:          class: phpbb_template_twig          arguments: diff --git a/phpBB/includes/functions.php b/phpBB/includes/functions.php index bf973fe141..ab4df9be54 100644 --- a/phpBB/includes/functions.php +++ b/phpBB/includes/functions.php @@ -7,8 +7,6 @@  *  */ -use Symfony\Component\HttpFoundation\Request; -  /**  * @ignore  */ @@ -2411,9 +2409,9 @@ function phpbb_on_page($template, $user, $base_url, $num_items, $per_page, $star  */  function append_sid($url, $params = false, $is_amp = true, $session_id = false)  { -	global $_SID, $_EXTRA_URL, $phpbb_hook; +	global $_SID, $_EXTRA_URL, $phpbb_hook, $phpbb_filesystem;  	global $phpbb_dispatcher; -	global $symfony_request, $phpbb_root_path; +	global $symfony_request, $phpbb_root_path, $phpbb_container;  	if ($params === '' || (is_array($params) && empty($params)))  	{ @@ -2421,10 +2419,10 @@ function append_sid($url, $params = false, $is_amp = true, $session_id = false)  		$params = false;  	} -	$corrected_path = $symfony_request !== null ? phpbb_get_web_root_path($symfony_request, $phpbb_root_path) : ''; -	if ($corrected_path) +	// Update the root path with the correct relative web path +	if ($phpbb_filesystem instanceof phpbb_filesystem)  	{ -		$url = substr($corrected_path . $url, strlen($phpbb_root_path)); +		$url = $phpbb_filesystem->update_web_root_path($url, $symfony_request);  	}  	$append_sid_overwrite = false; @@ -2816,8 +2814,22 @@ function build_url($strip_vars = false)  {  	global $user, $phpbb_root_path; +	$page = $user->page['page']; + +	// We need to be cautious here. +	// On some situations, the redirect path is an absolute URL, sometimes a relative path +	// For a relative path, let's prefix it with $phpbb_root_path to point to the correct location, +	// else we use the URL directly. +	$url_parts = @parse_url($page); + +	// URL +	if ($url_parts !== false && !empty($url_parts['scheme']) && !empty($url_parts['host'])) +	{ +		$page = $phpbb_root_path . $page; +	} +  	// Append SID -	$redirect = append_sid($user->page['page'], false, false); +	$redirect = append_sid($page, false, false);  	// Add delimiter if not there...  	if (strpos($redirect, '?') === false) @@ -2872,19 +2884,7 @@ function build_url($strip_vars = false)  		$redirect .= ($query) ? '?' . $query : '';  	} -	// We need to be cautious here. -	// On some situations, the redirect path is an absolute URL, sometimes a relative path -	// For a relative path, let's prefix it with $phpbb_root_path to point to the correct location, -	// else we use the URL directly. -	$url_parts = @parse_url($redirect); - -	// URL -	if ($url_parts !== false && !empty($url_parts['scheme']) && !empty($url_parts['host'])) -	{ -		return str_replace('&', '&', $redirect); -	} - -	return $phpbb_root_path . str_replace('&', '&', $redirect); +	return str_replace('&', '&', $redirect);  }  /** @@ -5081,7 +5081,7 @@ function phpbb_build_hidden_fields_for_query_params($request, $exclude = null)  function page_header($page_title = '', $display_online_list = true, $item_id = 0, $item = 'forum')  {  	global $db, $config, $template, $SID, $_SID, $_EXTRA_URL, $user, $auth, $phpEx, $phpbb_root_path; -	global $phpbb_dispatcher, $request, $phpbb_container, $symfony_request; +	global $phpbb_dispatcher, $request, $phpbb_container, $symfony_request, $adm_relative_path;  	if (defined('HEADER_INC'))  	{ @@ -5241,7 +5241,8 @@ function page_header($page_title = '', $display_online_list = true, $item_id = 0  	// This path is sent with the base template paths in the assign_vars()  	// call below. We need to correct it in case we are accessing from a  	// controller because the web paths will be incorrect otherwise. -	$corrected_path = $symfony_request !== null ? phpbb_get_web_root_path($symfony_request, $phpbb_root_path) : ''; +	$phpbb_filesystem = $phpbb_container->get('filesystem'); +	$corrected_path = $phpbb_filesystem->get_web_root_path($symfony_request);  	$web_path = (defined('PHPBB_USE_BOARD_URL_PATH') && PHPBB_USE_BOARD_URL_PATH) ? $board_url : $corrected_path;  	// Send a proper content-language to the output @@ -5380,7 +5381,7 @@ function page_header($page_title = '', $display_online_list = true, $item_id = 0  		'S_FORUM_ID'			=> $forum_id,  		'S_TOPIC_ID'			=> $topic_id, -		'S_LOGIN_ACTION'		=> ((!defined('ADMIN_START')) ? append_sid("{$phpbb_root_path}ucp.$phpEx", 'mode=login') : append_sid("index.$phpEx", false, true, $user->session_id)), +		'S_LOGIN_ACTION'		=> ((!defined('ADMIN_START')) ? append_sid("{$phpbb_root_path}ucp.$phpEx", 'mode=login') : append_sid("{$phpbb_root_path}{$adm_relative_path}index.$phpEx", false, true, $user->session_id)),  		'S_LOGIN_REDIRECT'		=> build_hidden_fields(array('redirect' => build_url())),  		'S_ENABLE_FEEDS'			=> ($config['feed_enable']) ? true : false, @@ -5707,83 +5708,3 @@ function phpbb_convert_30_dbms_to_31($dbms)  	throw new \RuntimeException("You have specified an invalid dbms driver: $dbms");  } - -/** -* Create a Symfony Request object from phpbb_request object -* -* @param phpbb_request $request Request object -* @return Request A Symfony Request object -*/ -function phpbb_create_symfony_request(phpbb_request $request) -{ -	// If we have already gotten it, don't go back through all the trouble of -	// creating it again; instead, just return it. This allows multiple calls -	// of this method so we don't have to globalize $symfony_request in other -	// functions. -	static $symfony_request; -	if (null !== $symfony_request) -	{ -		return $symfony_request; -	} - -	// This function is meant to sanitize the global input arrays -	$sanitizer = function(&$value, $key) { -		$type_cast_helper = new phpbb_request_type_cast_helper(); -		$type_cast_helper->set_var($value, $value, gettype($value), true); -	}; - -	// We need to re-enable the super globals so we can access them here -	$request->enable_super_globals(); -	$get_parameters = $_GET; -	$post_parameters = $_POST; -	$server_parameters = $_SERVER; -	$files_parameters = $_FILES; -	$cookie_parameters = $_COOKIE; -	// And now disable them again for security -	$request->disable_super_globals(); - -	array_walk_recursive($get_parameters, $sanitizer); -	array_walk_recursive($post_parameters, $sanitizer); - -	$symfony_request = new Request($get_parameters, $post_parameters, array(), $cookie_parameters, $files_parameters, $server_parameters); -	return $symfony_request; -} - -/** -* Get a relative root path from the current URL -* -* @param Request $symfony_request Symfony Request object -*/ -function phpbb_get_web_root_path(Request $symfony_request, $phpbb_root_path = '') -{ -	global $phpbb_container; - -	static $path; -	if (null !== $path) -	{ -		return $path; -	} - -	$path_info = $symfony_request->getPathInfo(); -	if ($path_info === '/') -	{ -		$path = $phpbb_root_path; -		return $path; -	} - -	$filesystem = $phpbb_container->get('filesystem'); -	$path_info = $filesystem->clean_path($path_info); - -	// Do not count / at start of path -	$corrections = substr_count(substr($path_info, 1), '/'); - -	// When URL Rewriting is enabled, app.php is optional. We have to -	// correct for it not being there -	if (strpos($symfony_request->getRequestUri(), $symfony_request->getScriptName()) === false) -	{ -		$corrections -= 1; -	} - -	$path = $phpbb_root_path . str_repeat('../', $corrections); -	return $path; -} diff --git a/phpBB/phpbb/filesystem.php b/phpBB/phpbb/filesystem.php index 27cab48fb0..e6c36375af 100644 --- a/phpBB/phpbb/filesystem.php +++ b/phpBB/phpbb/filesystem.php @@ -6,6 +6,7 @@  * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2  *  */ +  /**  * @ignore  */ @@ -20,6 +21,122 @@ if (!defined('IN_PHPBB'))  */  class phpbb_filesystem  { +	/** @var phpbb_symfony_request */ +	protected $symfony_request; + +	/** @var string */ +	protected $phpbb_root_path; + +	/** @var string */ +	protected $web_root_path; + +	/** +	* Constructor +	* +	* @param phpbb_symfony_request $symfony_request +	* @param string $phpbb_root_path +	*/ +	public function __construct(phpbb_symfony_request $symfony_request, $phpbb_root_path) +	{ +		$this->symfony_request = $symfony_request; +		$this->phpbb_root_path = $phpbb_root_path; +	} + +	/** +	* Get the phpBB root path +	* +	* @return string +	*/ +	public function get_phpbb_root_path() +	{ +		return $this->phpbb_root_path; +	} + +	/** +	* Update a path to the correct relative root path +	* +	* This replaces $phpbb_root_path . some_url with +	*	get_web_root_path() . some_url OR if $phpbb_root_path +	*	is not at the beginning of $path, just prepends the +	*	web root path +	* +	* @param string $path The path to be updated +	* @return string +	*/ +	public function update_web_root_path($path) +	{ +		$web_root_path = $this->get_web_root_path($this->symfony_request); + +		if (strpos($path, $this->phpbb_root_path) === 0) +		{ +			$path = substr($path, strlen($this->phpbb_root_path)); +		} + +		return $web_root_path . $path; +	} + +	/** +	* Get a relative root path from the current URL +	* +	* @return string +	*/ +	public function get_web_root_path() +	{ +		if ($this->symfony_request === null) +		{ +			return $this->phpbb_root_path; +		} + +		if (null !== $this->web_root_path) +		{ +			return $this->web_root_path; +		} + +		// Path info (e.g. /foo/bar) +		$path_info = $this->clean_path($this->symfony_request->getPathInfo()); + +		// Full request URI (e.g. phpBB/app.php/foo/bar) +		$request_uri = $this->symfony_request->getRequestUri(); + +		// Script name URI (e.g. phpBB/app.php) +		$script_name = $this->symfony_request->getScriptName(); + +		/* +		* If the path info is empty (single /), then we're not using +		*	a route like app.php/foo/bar +		*/ +		if ($path_info === '/') +		{ +			return $this->web_root_path = $this->phpbb_root_path; +		} + +		// How many corrections might we need? +		$corrections = substr_count($path_info, '/'); + +		/* +		* If the script name (e.g. phpBB/app.php) exists in the +		*	requestUri (e.g. phpBB/app.php/foo/template), then we +		*	are have a non-rewritten URL. +		*/ +		if (strpos($request_uri, $script_name) === 0) +		{ +			/* +			* Append ../ to the end of the phpbb_root_path as many times +			*	as / exists in path_info +			*/ +			return $this->web_root_path = $this->phpbb_root_path . str_repeat('../', $corrections); +		} + +		/* +		* If we're here it means we're at a re-written path, so we must +		*	correct the relative path for web URLs. We must append ../ +		*	to the end of the root path as many times as / exists in path_info +		*	less one time (because the script, e.g. /app.php, doesn't exist in +		*	the URL) +		*/ +		return $this->web_root_path = $this->phpbb_root_path . str_repeat('../', $corrections - 1); +	} +  	/**  	* Eliminates useless . and .. components from specified path.  	* diff --git a/phpBB/phpbb/symfony_request.php b/phpBB/phpbb/symfony_request.php new file mode 100644 index 0000000000..29ab8c000e --- /dev/null +++ b/phpBB/phpbb/symfony_request.php @@ -0,0 +1,46 @@ +<?php +/** +* +* @package phpBB3 +* @copyright (c) 2013 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +use Symfony\Component\HttpFoundation\Request; + +/** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ +	exit; +} + +class phpbb_symfony_request extends Request +{ +	/** +	* Constructor +	* +	* @param phpbb_request_interface $phpbb_request +	*/ +	public function __construct(phpbb_request_interface $phpbb_request) +	{ +		// This function is meant to sanitize the global input arrays +		$sanitizer = function(&$value, $key) { +			$type_cast_helper = new phpbb_request_type_cast_helper(); +			$type_cast_helper->set_var($value, $value, gettype($value), true); +		}; + +		$get_parameters = $phpbb_request->get_super_global(phpbb_request_interface::GET); +		$post_parameters = $phpbb_request->get_super_global(phpbb_request_interface::POST); +		$server_parameters = $phpbb_request->get_super_global(phpbb_request_interface::SERVER); +		$files_parameters = $phpbb_request->get_super_global(phpbb_request_interface::FILES); +		$cookie_parameters = $phpbb_request->get_super_global(phpbb_request_interface::COOKIE); + +		array_walk_recursive($get_parameters, $sanitizer); +		array_walk_recursive($post_parameters, $sanitizer); + +		parent::__construct($get_parameters, $post_parameters, array(), $cookie_parameters, $files_parameters, $server_parameters); +	} +} diff --git a/tests/dbal/migrator_test.php b/tests/dbal/migrator_test.php index 9e55e4dd35..4be1fbe176 100644 --- a/tests/dbal/migrator_test.php +++ b/tests/dbal/migrator_test.php @@ -59,7 +59,7 @@ class phpbb_dbal_migrator_test extends phpbb_database_test_case  			$container,  			$this->db,  			$this->config, -			new phpbb_filesystem(), +			new phpbb_filesystem(dirname(__FILE__) . '/../../phpBB/'),  			'phpbb_ext',  			dirname(__FILE__) . '/../../phpBB/',  			'php', diff --git a/tests/extension/manager_test.php b/tests/extension/manager_test.php index a23e5a18d9..2da6ba5df5 100644 --- a/tests/extension/manager_test.php +++ b/tests/extension/manager_test.php @@ -114,7 +114,7 @@ class phpbb_extension_manager_test extends phpbb_database_test_case  			$container,  			$db,  			$config, -			new phpbb_filesystem(), +			new phpbb_filesystem($phpbb_root_path),  			'phpbb_ext',  			dirname(__FILE__) . '/',  			$php_ext, diff --git a/tests/extension/metadata_manager_test.php b/tests/extension/metadata_manager_test.php index e5bd29092e..594568b805 100644 --- a/tests/extension/metadata_manager_test.php +++ b/tests/extension/metadata_manager_test.php @@ -65,7 +65,7 @@ class phpbb_extension_metadata_manager_test extends phpbb_database_test_case  			$container,  			$this->db,  			$this->config, -			new phpbb_filesystem(), +			new phpbb_filesystem($this->phpbb_root_path),  			'phpbb_ext',  			$this->phpbb_root_path,  			$this->phpEx, diff --git a/tests/filesystem/clean_path_test.php b/tests/filesystem/clean_path_test.php index 50951fc88c..b79668fc33 100644 --- a/tests/filesystem/clean_path_test.php +++ b/tests/filesystem/clean_path_test.php @@ -14,7 +14,12 @@ class phpbb_filesystem_clean_path_test extends phpbb_test_case  	public function setUp()  	{  		parent::setUp(); -		$this->filesystem = new phpbb_filesystem(); +		$this->filesystem = new phpbb_filesystem( +			new phpbb_symfony_request( +				new phpbb_mock_request() +			), +			dirname(__FILE__) . './../../phpBB/' +		);  	}  	public function clean_path_data() diff --git a/tests/filesystem/web_root_path_test.php b/tests/filesystem/web_root_path_test.php new file mode 100644 index 0000000000..b681c26de9 --- /dev/null +++ b/tests/filesystem/web_root_path_test.php @@ -0,0 +1,133 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2013 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +class phpbb_filesystem_web_root_path_test extends phpbb_test_case +{ +	protected $filesystem; +	protected $phpbb_root_path = ''; + +	public function setUp() +	{ +		parent::setUp(); + +		$this->set_phpbb_root_path(); + +		$symfony_request = new phpbb_symfony_request(new phpbb_mock_request()); +		$this->filesystem = new phpbb_filesystem($symfony_request, $this->phpbb_root_path); +	} + +	/** +	* Set the phpbb_root_path +	* +	* This is necessary because dataProvider functions are called +	*	before setUp or setUpBeforeClass; so we must set the path +	*	any time we wish to use it in one of these functions (and +	*	also in general for everything else) +	*/ +	public function set_phpbb_root_path() +	{ +		$this->phpbb_root_path = dirname(__FILE__) . './../../phpBB/'; +	} + +	public function test_get_web_root_path() +	{ +		// Symfony Request = null, so always should return phpbb_root_path +		$this->assertEquals($this->phpbb_root_path, $this->filesystem->get_web_root_path()); +	} + +	public function basic_update_web_root_path_data() +	{ +		$this->set_phpbb_root_path(); + +		return array( +			array( +				$this->phpbb_root_path . 'test.php', +				$this->phpbb_root_path . 'test.php', +			), +			array( +				'test.php', +				$this->phpbb_root_path . 'test.php', +			), +			array( +				$this->phpbb_root_path . $this->phpbb_root_path . 'test.php', +				$this->phpbb_root_path . $this->phpbb_root_path . 'test.php', +			), +		); +	} + +	/** +	* @dataProvider basic_update_web_root_path_data +	*/ +	public function test_basic_update_web_root_path($input, $expected) +	{ +		$this->assertEquals($expected, $this->filesystem->update_web_root_path($input, $symfony_request)); +	} + +	public function update_web_root_path_data() +	{ +		$this->set_phpbb_root_path(); + +		return array( +			array( +				$this->phpbb_root_path . 'test.php', +				$this->phpbb_root_path . 'test.php', +				'/', +			), +			array( +				$this->phpbb_root_path . 'test.php', +				$this->phpbb_root_path . '../test.php', +				'//', +			), +			array( +				$this->phpbb_root_path . 'test.php', +				$this->phpbb_root_path . '../test.php', +				'//', +				'foo/bar.php', +				'bar.php', +			), +			array( +				$this->phpbb_root_path . 'test.php', +				$this->phpbb_root_path . '../../test.php', +				'/foo/template', +				'/phpbb3-fork/phpBB/app.php/foo/template', +				'/phpbb3-fork/phpBB/app.php', +			), +			array( +				$this->phpbb_root_path . 'test.php', +				$this->phpbb_root_path . '../test.php', +				'/foo/template', +				'/phpbb3-fork/phpBB/foo/template', +				'/phpbb3-fork/phpBB/app.php', +			), +		); +	} + +	/** +	* @dataProvider update_web_root_path_data +	*/ +	public function test_update_web_root_path($input, $expected, $getPathInfo, $getRequestUri = null, $getScriptName = null) +	{ +		$symfony_request = $this->getMock("phpbb_symfony_request", array(), array( +			new phpbb_mock_request(), +		)); +		$symfony_request->expects($this->any()) +			->method('getPathInfo') +			->will($this->returnValue($getPathInfo)); +		$symfony_request->expects($this->any()) +			->method('getRequestUri') +			->will($this->returnValue($getRequestUri)); +		$symfony_request->expects($this->any()) +			->method('getScriptName') +			->will($this->returnValue($getScriptName)); + +		$filesystem = new phpbb_filesystem($symfony_request, $this->phpbb_root_path); + +		$this->assertEquals($expected, $filesystem->update_web_root_path($input, $symfony_request)); +	} +} diff --git a/tests/log/function_view_log_test.php b/tests/log/function_view_log_test.php index 6827aaa1b6..a634863fb6 100644 --- a/tests/log/function_view_log_test.php +++ b/tests/log/function_view_log_test.php @@ -23,8 +23,10 @@ class phpbb_log_function_view_log_test extends phpbb_database_test_case  	public static function view_log_function_data()  	{ -		global $phpEx, $phpbb_dispatcher; +		global $phpEx, $phpbb_dispatcher, $phpbb_container, $phpbb_root_path;  		$phpbb_dispatcher = new phpbb_mock_event_dispatcher(); +		$phpbb_container = new phpbb_mock_container_builder(); +		$phpbb_container->set('filesystem', new phpbb_filesystem($phpbb_root_path));  		$expected_data_sets = array(  			1 => array( diff --git a/tests/mock/extension_manager.php b/tests/mock/extension_manager.php index 10b3595206..28eec5930f 100644 --- a/tests/mock/extension_manager.php +++ b/tests/mock/extension_manager.php @@ -14,6 +14,6 @@ class phpbb_mock_extension_manager extends phpbb_extension_manager  		$this->phpbb_root_path = $phpbb_root_path;  		$this->php_ext = 'php';  		$this->extensions = $extensions; -		$this->filesystem = new phpbb_filesystem(); +		$this->filesystem = new phpbb_filesystem($phpbb_root_path);  	}  } diff --git a/tests/test_framework/phpbb_functional_test_case.php b/tests/test_framework/phpbb_functional_test_case.php index eb40cddfe5..579e225ed9 100644 --- a/tests/test_framework/phpbb_functional_test_case.php +++ b/tests/test_framework/phpbb_functional_test_case.php @@ -203,7 +203,7 @@ class phpbb_functional_test_case extends phpbb_test_case  			$container,  			$db,  			$config, -			new phpbb_filesystem(), +			new phpbb_filesystem($phpbb_root_path),  			self::$config['table_prefix'] . 'ext',  			dirname(__FILE__) . '/',  			$php_ext,  | 
