diff options
-rw-r--r-- | phpBB/common.php | 3 | ||||
-rw-r--r-- | phpBB/config/services.yml | 2 | ||||
-rw-r--r-- | phpBB/includes/functions.php | 56 | ||||
-rw-r--r-- | phpBB/phpbb/filesystem.php | 115 | ||||
-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 | 2 | ||||
-rw-r--r-- | tests/filesystem/web_root_path_test.php | 116 | ||||
-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 |
12 files changed, 252 insertions, 56 deletions
diff --git a/phpBB/common.php b/phpBB/common.php index a7b7db28ac..bfbc5989aa 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; @@ -101,6 +101,7 @@ $cache = $phpbb_container->get('cache'); // Instantiate some basic classes $phpbb_dispatcher = $phpbb_container->get('dispatcher'); +$phpbb_filesystem = $phpbb_container->get('filesystem'); $request = $phpbb_container->get('request'); $user = $phpbb_container->get('user'); $auth = $phpbb_container->get('auth'); diff --git a/phpBB/config/services.yml b/phpBB/config/services.yml index 2808e81337..01e470f87f 100644 --- a/phpBB/config/services.yml +++ b/phpBB/config/services.yml @@ -169,6 +169,8 @@ services: filesystem: class: phpbb_filesystem + arguments: + - %core.root_path% groupposition.legend: class: phpbb_groupposition_legend diff --git a/phpBB/includes/functions.php b/phpBB/includes/functions.php index bf973fe141..2f13de88b6 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; @@ -5241,7 +5239,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 @@ -5745,45 +5744,6 @@ function phpbb_create_symfony_request(phpbb_request $request) 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); + $symfony_request = new Symfony\Component\HttpFoundation\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..5d70b88a29 100644 --- a/phpBB/phpbb/filesystem.php +++ b/phpBB/phpbb/filesystem.php @@ -6,6 +6,9 @@ * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ + +use Symfony\Component\HttpFoundation\Request; + /** * @ignore */ @@ -20,6 +23,118 @@ if (!defined('IN_PHPBB')) */ class phpbb_filesystem { + /** @var string */ + protected $phpbb_root_path; + + /** @var string */ + protected $web_root_path; + + /** + * Constructor + * + * @param string $phpbb_root_path + */ + public function __construct($phpbb_root_path) + { + $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 Request $symfony_request Symfony Request object + * @return string + */ + public function update_web_root_path($path, Request $symfony_request = null) + { + $web_root_path = $this->get_web_root_path($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 + * + * @param Request $symfony_request Symfony Request object + * @return string + */ + public function get_web_root_path(Request $symfony_request = null) + { + if ($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($symfony_request->getPathInfo()); + + // Full request URI (e.g. phpBB/app.php/foo/bar) + $request_uri = $symfony_request->getRequestUri(); + + // Script name URI (e.g. phpBB/app.php) + $script_name = $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/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..88352838bb 100644 --- a/tests/filesystem/clean_path_test.php +++ b/tests/filesystem/clean_path_test.php @@ -14,7 +14,7 @@ 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(__DIR__ . './../../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..8e0ba278e0 --- /dev/null +++ b/tests/filesystem/web_root_path_test.php @@ -0,0 +1,116 @@ +<?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(); + + $this->filesystem = new phpbb_filesystem($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 update_web_root_path_data() + { + $this->set_phpbb_root_path(); + + return array( + array( + $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', + ), + 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 = null, $getPathInfo = null, $getRequestUri = null, $getScriptName = null) + { + $expected = ($expected === null) ? $input : $expected; + + $symfony_request = null; + if ($getPathInfo !== null) + { + $symfony_request = $this->getMock("Symfony\Component\HttpFoundation\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)); + } + + $this->assertEquals($expected, $this->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 ce748bb9cf..dedaf4cd68 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, |