diff options
-rw-r--r-- | phpBB/.htaccess | 24 | ||||
-rw-r--r-- | phpBB/app.php | 1 | ||||
-rw-r--r-- | phpBB/common.php | 3 | ||||
-rw-r--r-- | phpBB/config/services.yml | 1 | ||||
-rw-r--r-- | phpBB/includes/functions.php | 67 | ||||
-rw-r--r-- | phpBB/phpbb/controller/helper.php | 33 | ||||
-rw-r--r-- | phpBB/phpbb/template/twig/lexer.php | 2 | ||||
-rw-r--r-- | tests/controller/helper_url_test.php | 32 | ||||
-rw-r--r-- | tests/functional/extension_controller_test.php | 10 | ||||
-rw-r--r-- | tests/template/template_test.php | 2 | ||||
-rw-r--r-- | tests/template/templates/define.html | 2 | ||||
-rwxr-xr-x | travis/setup-webserver.sh | 2 |
12 files changed, 122 insertions, 57 deletions
diff --git a/phpBB/.htaccess b/phpBB/.htaccess index 474f9774c2..6f33916775 100644 --- a/phpBB/.htaccess +++ b/phpBB/.htaccess @@ -1,12 +1,30 @@ +<IfModule mod_rewrite.c> +RewriteEngine on + # # Uncomment the statement below if you want to make use of # HTTP authentication and it does not already work. # This could be required if you are for example using PHP via Apache CGI. # -#<IfModule mod_rewrite.c> -#RewriteEngine on #RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization},L] -#</IfModule> + +# +# The following 3 lines will rewrite URLs passed through the front controller +# to not require app.php in the actual URL. In other words, a controller is +# by default accessed at /app.php/my/controller, but can also be accessed at +# /my/controller +# +RewriteCond %{REQUEST_FILENAME} !-f +RewriteCond %{REQUEST_FILENAME} !-d +RewriteRule ^(.*)$ app.php [QSA,L] + +# +# If symbolic links are not already being followed, +# uncomment the line below. +# http://anothersysadmin.wordpress.com/2008/06/10/mod_rewrite-forbidden-403-with-apache-228/ +# +#Options +FollowSymLinks +</IfModule> <Files "config.php"> Order Allow,Deny diff --git a/phpBB/app.php b/phpBB/app.php index d93208d585..f1023ff1b5 100644 --- a/phpBB/app.php +++ b/phpBB/app.php @@ -24,7 +24,6 @@ $user->session_begin(); $auth->acl($user->data); $user->setup('app'); -$symfony_request = phpbb_create_symfony_request($request); $http_kernel = $phpbb_container->get('http_kernel'); $response = $http_kernel->handle($symfony_request); $response->send(); diff --git a/phpBB/common.php b/phpBB/common.php index 6a1f307d64..a7b7db28ac 100644 --- a/phpBB/common.php +++ b/phpBB/common.php @@ -109,6 +109,9 @@ $db = $phpbb_container->get('dbal.conn'); // make sure request_var uses this request instance 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); + // Grab global variables, re-cache if necessary $config = $phpbb_container->get('config'); set_config(null, null, null, $config); diff --git a/phpBB/config/services.yml b/phpBB/config/services.yml index d0753322da..2808e81337 100644 --- a/phpBB/config/services.yml +++ b/phpBB/config/services.yml @@ -90,6 +90,7 @@ services: arguments: - @template - @user + - @request - %core.root_path% - %core.php_ext% diff --git a/phpBB/includes/functions.php b/phpBB/includes/functions.php index 3db843ffd1..4d2d704a43 100644 --- a/phpBB/includes/functions.php +++ b/phpBB/includes/functions.php @@ -2413,6 +2413,7 @@ function append_sid($url, $params = false, $is_amp = true, $session_id = false) { global $_SID, $_EXTRA_URL, $phpbb_hook; global $phpbb_dispatcher; + global $symfony_request, $phpbb_root_path; if ($params === '' || (is_array($params) && empty($params))) { @@ -2420,6 +2421,12 @@ 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) + { + $url = substr($corrected_path . $url, strlen($phpbb_root_path)); + } + $append_sid_overwrite = false; /** @@ -5051,7 +5058,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; + global $phpbb_dispatcher, $request, $phpbb_container, $symfony_request; if (defined('HEADER_INC')) { @@ -5208,7 +5215,11 @@ function page_header($page_title = '', $display_online_list = true, $item_id = 0 // Determine board url - we may need it later $board_url = generate_board_url() . '/'; - $web_path = (defined('PHPBB_USE_BOARD_URL_PATH') && PHPBB_USE_BOARD_URL_PATH) ? $board_url : $phpbb_root_path; + // 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) : ''; + $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 $user_lang = $user->lang['USER_LANG']; @@ -5682,6 +5693,16 @@ function phpbb_convert_30_dbms_to_31($dbms) */ 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(); @@ -5701,21 +5722,39 @@ function phpbb_create_symfony_request(phpbb_request $request) array_walk_recursive($get_parameters, $sanitizer); array_walk_recursive($post_parameters, $sanitizer); - // Until we fix the issue with relative paths, we have to fake path info - // to allow urls like app.php?controller=foo/bar - $controller = $request->variable('controller', ''); - $path_info = '/' . $controller; - $request_uri = $server_parameters['REQUEST_URI']; + $symfony_request = new Request($get_parameters, $post_parameters, array(), $cookie_parameters, $files_parameters, $server_parameters); + return $symfony_request; +} - // Remove the query string from REQUEST_URI - if ($pos = strpos($request_uri, '?')) +/** +* 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 = '') +{ + static $path; + if (null !== $path) + { + return $path; + } + + $path_info = $symfony_request->getPathInfo(); + if ($path_info === '/') { - $request_uri = substr($request_uri, 0, $pos); + $path = $phpbb_root_path; + return $path; } - // Add the path info (i.e. controller route) to the REQUEST_URI - $server_parameters['REQUEST_URI'] = $request_uri . $path_info; - $server_parameters['SCRIPT_NAME'] = ''; + $corrections = substr_count($path_info, '/'); + + // 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; + } - return new Request($get_parameters, $post_parameters, array(), $cookie_parameters, $files_parameters, $server_parameters); + $path = $phpbb_root_path . str_repeat('../', $corrections); + return $path; } diff --git a/phpBB/phpbb/controller/helper.php b/phpBB/phpbb/controller/helper.php index 74410ddfd1..4d240f9380 100644 --- a/phpBB/phpbb/controller/helper.php +++ b/phpBB/phpbb/controller/helper.php @@ -36,6 +36,12 @@ class phpbb_controller_helper protected $user; /** + * Request object + * @var phpbb_request + */ + protected $request; + + /** * phpBB root path * @var string */ @@ -55,10 +61,11 @@ class phpbb_controller_helper * @param string $phpbb_root_path phpBB root path * @param string $php_ext PHP extension */ - public function __construct(phpbb_template $template, phpbb_user $user, $phpbb_root_path, $php_ext) + public function __construct(phpbb_template $template, phpbb_user $user, phpbb_request_interface $request, $phpbb_root_path, $php_ext) { $this->template = $template; $this->user = $user; + $this->request = $request; $this->phpbb_root_path = $phpbb_root_path; $this->php_ext = $php_ext; } @@ -102,22 +109,16 @@ class phpbb_controller_helper $route = substr($route, 0, $route_delim); } - if (is_array($params) && !empty($params)) - { - $params = array_merge(array( - 'controller' => $route, - ), $params); - } - else if (is_string($params) && $params) - { - $params = 'controller=' . $route . (($is_amp) ? '&' : '&') . $params; - } - else - { - $params = array('controller' => $route); - } + $request_uri = $this->request->variable('REQUEST_URI', '', false, phpbb_request::SERVER); + $script_name = $this->request->variable('SCRIPT_NAME', '', false, phpbb_request::SERVER); + + // If the app.php file is being used (no rewrite) keep it in the URL. + // Otherwise, don't include it. + $route_prefix = $this->phpbb_root_path; + $parts = explode('/', $script_name); + $route_prefix .= strpos($request_uri, $script_name) === 0 ? array_pop($parts) . '/' : ''; - return append_sid($this->phpbb_root_path . 'app.' . $this->php_ext . $route_params, $params, $is_amp, $session_id); + return append_sid($route_prefix . "$route" . $route_params, $params, $is_amp, $session_id); } /** diff --git a/phpBB/phpbb/template/twig/lexer.php b/phpBB/phpbb/template/twig/lexer.php index a33de70d69..7ab569313c 100644 --- a/phpBB/phpbb/template/twig/lexer.php +++ b/phpBB/phpbb/template/twig/lexer.php @@ -130,7 +130,7 @@ class phpbb_template_twig_lexer extends Twig_Lexer // E.g. 'asdf'"' -> asdf'" // E.g. "asdf'"" -> asdf'" // E.g. 'asdf'" -> 'asdf'" - $matches[2] = preg_replace('#^([\'"])?(.+?)\1$#', '$2', $matches[2]); + $matches[2] = preg_replace('#^([\'"])?(.*?)\1$#', '$2', $matches[2]); // Replace template variables with start/end to parse variables (' ~ TEST ~ '.html) $matches[2] = preg_replace('#{([a-zA-Z0-9_\.$]+)}#', "'~ \$1 ~'", $matches[2]); diff --git a/tests/controller/helper_url_test.php b/tests/controller/helper_url_test.php index fc7d02e9cf..49635332a7 100644 --- a/tests/controller/helper_url_test.php +++ b/tests/controller/helper_url_test.php @@ -15,28 +15,28 @@ class phpbb_controller_helper_url_test extends phpbb_test_case public function helper_url_data() { return array( - array('foo/bar?t=1&f=2', false, true, false, 'app.php?t=1&f=2&controller=foo/bar', 'parameters in url-argument'), - array('foo/bar', 't=1&f=2', true, false, 'app.php?controller=foo/bar&t=1&f=2', 'parameters in params-argument using amp'), - array('foo/bar', 't=1&f=2', false, false, 'app.php?controller=foo/bar&t=1&f=2', 'parameters in params-argument using &'), - array('foo/bar', array('t' => 1, 'f' => 2), true, false, 'app.php?controller=foo/bar&t=1&f=2', 'parameters in params-argument as array'), + array('foo/bar?t=1&f=2', false, true, false, 'foo/bar?t=1&f=2', 'parameters in url-argument'), + array('foo/bar', 't=1&f=2', true, false, 'foo/bar?t=1&f=2', 'parameters in params-argument using amp'), + array('foo/bar', 't=1&f=2', false, false, 'foo/bar?t=1&f=2', 'parameters in params-argument using &'), + array('foo/bar', array('t' => 1, 'f' => 2), true, false, 'foo/bar?t=1&f=2', 'parameters in params-argument as array'), // Custom sid parameter - array('foo/bar', 't=1&f=2', true, 'custom-sid', 'app.php?controller=foo/bar&t=1&f=2&sid=custom-sid', 'using session_id'), + array('foo/bar', 't=1&f=2', true, 'custom-sid', 'foo/bar?t=1&f=2&sid=custom-sid', 'using session_id'), // Testing anchors - array('foo/bar?t=1&f=2#anchor', false, true, false, 'app.php?t=1&f=2&controller=foo/bar#anchor', 'anchor in url-argument'), - array('foo/bar', 't=1&f=2#anchor', true, false, 'app.php?controller=foo/bar&t=1&f=2#anchor', 'anchor in params-argument'), - array('foo/bar', array('t' => 1, 'f' => 2, '#' => 'anchor'), true, false, 'app.php?controller=foo/bar&t=1&f=2#anchor', 'anchor in params-argument (array)'), + array('foo/bar?t=1&f=2#anchor', false, true, false, 'foo/bar?t=1&f=2#anchor', 'anchor in url-argument'), + array('foo/bar', 't=1&f=2#anchor', true, false, 'foo/bar?t=1&f=2#anchor', 'anchor in params-argument'), + array('foo/bar', array('t' => 1, 'f' => 2, '#' => 'anchor'), true, false, 'foo/bar?t=1&f=2#anchor', 'anchor in params-argument (array)'), // Anchors and custom sid - array('foo/bar?t=1&f=2#anchor', false, true, 'custom-sid', 'app.php?t=1&f=2&controller=foo/bar&sid=custom-sid#anchor', 'anchor in url-argument using session_id'), - array('foo/bar', 't=1&f=2#anchor', true, 'custom-sid', 'app.php?controller=foo/bar&t=1&f=2&sid=custom-sid#anchor', 'anchor in params-argument using session_id'), - array('foo/bar', array('t' => 1, 'f' => 2, '#' => 'anchor'), true, 'custom-sid', 'app.php?controller=foo/bar&t=1&f=2&sid=custom-sid#anchor', 'anchor in params-argument (array) using session_id'), + array('foo/bar?t=1&f=2#anchor', false, true, 'custom-sid', 'foo/bar?t=1&f=2&sid=custom-sid#anchor', 'anchor in url-argument using session_id'), + array('foo/bar', 't=1&f=2#anchor', true, 'custom-sid', 'foo/bar?t=1&f=2&sid=custom-sid#anchor', 'anchor in params-argument using session_id'), + array('foo/bar', array('t' => 1, 'f' => 2, '#' => 'anchor'), true, 'custom-sid', 'foo/bar?t=1&f=2&sid=custom-sid#anchor', 'anchor in params-argument (array) using session_id'), // Empty parameters should not append the & - array('foo/bar', false, true, false, 'app.php?controller=foo/bar', 'no params using bool false'), - array('foo/bar', '', true, false, 'app.php?controller=foo/bar', 'no params using empty string'), - array('foo/bar', array(), true, false, 'app.php?controller=foo/bar', 'no params using empty array'), + array('foo/bar', false, true, false, 'foo/bar', 'no params using bool false'), + array('foo/bar', '', true, false, 'foo/bar', 'no params using empty string'), + array('foo/bar', array(), true, false, 'foo/bar', 'no params using empty array'), ); } @@ -51,7 +51,9 @@ class phpbb_controller_helper_url_test extends phpbb_test_case $this->user = $this->getMock('phpbb_user'); $this->template = new phpbb_template_twig($phpbb_root_path, $phpEx, $config, $this->user, new phpbb_template_context()); - $helper = new phpbb_controller_helper($this->template, $this->user, '', 'php'); + + $request = new phpbb_mock_request($_GET, $_POST, $_COOKIE, $_SERVER, false, $_FILES); + $helper = new phpbb_controller_helper($this->template, $this->user, $request, '', 'php'); $this->assertEquals($helper->url($route, $params, $is_amp, $session_id), $expected); } } diff --git a/tests/functional/extension_controller_test.php b/tests/functional/extension_controller_test.php index 7d29f0000c..dc6d9c0f65 100644 --- a/tests/functional/extension_controller_test.php +++ b/tests/functional/extension_controller_test.php @@ -52,7 +52,7 @@ class phpbb_functional_extension_controller_test extends phpbb_functional_test_c public function test_foo_bar() { $this->phpbb_extension_manager->enable('foo/bar'); - $crawler = self::request('GET', 'app.php?controller=foo/bar', array(), false); + $crawler = self::request('GET', 'app.php/foo/bar', array(), false); self::assert_response_status_code(); $this->assertContains("foo/bar controller handle() method", $crawler->filter('body')->text()); $this->phpbb_extension_manager->purge('foo/bar'); @@ -64,7 +64,7 @@ class phpbb_functional_extension_controller_test extends phpbb_functional_test_c public function test_controller_with_template() { $this->phpbb_extension_manager->enable('foo/bar'); - $crawler = self::request('GET', 'app.php?controller=foo/template'); + $crawler = self::request('GET', 'app.php/foo/template'); $this->assertContains("I am a variable", $crawler->filter('#content')->text()); $this->phpbb_extension_manager->purge('foo/bar'); } @@ -76,7 +76,7 @@ class phpbb_functional_extension_controller_test extends phpbb_functional_test_c public function test_missing_argument() { $this->phpbb_extension_manager->enable('foo/bar'); - $crawler = self::request('GET', 'app.php?controller=foo/baz', array(), false); + $crawler = self::request('GET', 'app.php/foo/baz', array(), false); $this->assert_response_html(500); $this->assertContains('Missing value for argument #1: test in class phpbb_ext_foo_bar_controller:baz', $crawler->filter('body')->text()); $this->phpbb_extension_manager->purge('foo/bar'); @@ -88,7 +88,7 @@ class phpbb_functional_extension_controller_test extends phpbb_functional_test_c public function test_exception_should_result_in_500_status_code() { $this->phpbb_extension_manager->enable('foo/bar'); - $crawler = self::request('GET', 'app.php?controller=foo/exception', array(), false); + $crawler = self::request('GET', 'app.php/foo/exception', array(), false); $this->assert_response_html(500); $this->assertContains('Exception thrown from foo/exception route', $crawler->filter('body')->text()); $this->phpbb_extension_manager->purge('foo/bar'); @@ -105,7 +105,7 @@ class phpbb_functional_extension_controller_test extends phpbb_functional_test_c */ public function test_error_ext_disabled_or_404() { - $crawler = self::request('GET', 'app.php?controller=does/not/exist', array(), false); + $crawler = self::request('GET', 'app.php/does/not/exist', array(), false); $this->assert_response_html(404); $this->assertContains('No route found for "GET /does/not/exist"', $crawler->filter('body')->text()); } diff --git a/tests/template/template_test.php b/tests/template/template_test.php index 38eb072df8..f2e3903458 100644 --- a/tests/template/template_test.php +++ b/tests/template/template_test.php @@ -158,7 +158,7 @@ class phpbb_template_template_test extends phpbb_template_template_test_case array(), array('test_loop' => array(array(), array(), array(), array(), array(), array(), array()), 'test' => array(array()), 'test.deep' => array(array()), 'test.deep.defines' => array(array())), array(), - "xyz\nabc\n\$VALUE == 'abc'abc\nbar\nbar\nabc\ntest!@#$%^&*()_-=+{}[]:;\",<.>/?", + "xyz\nabc\n\$VALUE == 'abc'abc\nbar\nbar\nabc\ntest!@#$%^&*()_-=+{}[]:;\",<.>/?\n[]", ), array( 'define_advanced.html', diff --git a/tests/template/templates/define.html b/tests/template/templates/define.html index 66e874ca63..e6c8ef49c9 100644 --- a/tests/template/templates/define.html +++ b/tests/template/templates/define.html @@ -14,3 +14,5 @@ $VALUE == 'abc' {$VALUE} <!-- DEFINE $VALUE = 'test!@#$%^&*()_-=+{}[]:;",<.>/?' --> {$VALUE} +<!-- DEFINE $VALUE = '' --> +[{$VALUE}] diff --git a/travis/setup-webserver.sh b/travis/setup-webserver.sh index beb04b0fef..95fc4ec1f8 100755 --- a/travis/setup-webserver.sh +++ b/travis/setup-webserver.sh @@ -42,7 +42,7 @@ server { root $PHPBB_ROOT_PATH/; index index.php index.html; - location ~ \.php$ { + location ~ \.php { fastcgi_pass unix:$PHP_FPM_SOCK; include fastcgi_params; } |