Fixed base URL detection when request URI contains encoded chars
Signed-off-by: Victor Berchet <victor@suumit.com>
This commit is contained in:
parent
127cff0aa8
commit
d17ba0e147
@ -1301,14 +1301,14 @@ class Request
|
||||
// Does the baseUrl have anything in common with the request_uri?
|
||||
$requestUri = $this->getRequestUri();
|
||||
|
||||
if ($baseUrl && 0 === strpos($requestUri, $baseUrl)) {
|
||||
if ($baseUrl && false !== $prefix = $this->getUrlencodedPrefix($requestUri, $baseUrl)) {
|
||||
// full $baseUrl matches
|
||||
return $baseUrl;
|
||||
return $prefix;
|
||||
}
|
||||
|
||||
if ($baseUrl && 0 === strpos($requestUri, dirname($baseUrl))) {
|
||||
if ($baseUrl && false !== $prefix = $this->getUrlencodedPrefix($requestUri, dirname($baseUrl))) {
|
||||
// directory portion of $baseUrl matches
|
||||
return rtrim(dirname($baseUrl), '/');
|
||||
return rtrim($prefix, '/');
|
||||
}
|
||||
|
||||
$truncatedRequestUri = $requestUri;
|
||||
@ -1317,7 +1317,7 @@ class Request
|
||||
}
|
||||
|
||||
$basename = basename($baseUrl);
|
||||
if (empty($basename) || !strpos($truncatedRequestUri, $basename)) {
|
||||
if (empty($basename) || !strpos(urldecode($truncatedRequestUri), $basename)) {
|
||||
// no match whatsoever; set it blank
|
||||
return '';
|
||||
}
|
||||
@ -1378,14 +1378,14 @@ class Request
|
||||
$requestUri = substr($requestUri, 0, $pos);
|
||||
}
|
||||
|
||||
if ((null !== $baseUrl) && (false === ($pathInfo = substr(urldecode($requestUri), strlen(urldecode($baseUrl)))))) {
|
||||
if ((null !== $baseUrl) && (false === ($pathInfo = substr($requestUri, strlen($baseUrl))))) {
|
||||
// If substr() returns false then PATH_INFO is set to an empty string
|
||||
return '/';
|
||||
} elseif (null === $baseUrl) {
|
||||
return $requestUri;
|
||||
}
|
||||
|
||||
return (string) $pathInfo;
|
||||
return rawurldecode((string) $pathInfo);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1423,4 +1423,28 @@ class Request
|
||||
} catch (\Exception $e) {
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the prefix as encoded in the string when the string starts with
|
||||
* the given prefix, false otherwise.
|
||||
*
|
||||
* @param string $string The urlencoded string
|
||||
* @param string $prefix The prefix not encoded
|
||||
*
|
||||
* @return string|false The prefix as it is encoded in $string, or false
|
||||
*/
|
||||
private function getUrlencodedPrefix($string, $prefix)
|
||||
{
|
||||
if (0 !== strpos(rawurldecode($string), $prefix)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$len = strlen($prefix);
|
||||
|
||||
if (preg_match("#^(%[[:xdigit:]]{2}|.){{$len}}#", $string, $match)) {
|
||||
return $match[0];
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -751,18 +751,11 @@ class RequestTest extends \PHPUnit_Framework_TestCase
|
||||
|
||||
$this->assertEquals('/path/info', $request->getPathInfo());
|
||||
|
||||
$server = array();
|
||||
$server['REQUEST_URI'] = '/path test/info';
|
||||
$request->initialize(array(), array(), array(), array(), array(), $server);
|
||||
|
||||
$this->assertEquals('/path test/info', $request->getPathInfo());
|
||||
|
||||
$server = array();
|
||||
$server['REQUEST_URI'] = '/path%20test/info';
|
||||
$request->initialize(array(), array(), array(), array(), array(), $server);
|
||||
|
||||
$this->assertEquals('/path test/info', $request->getPathInfo());
|
||||
|
||||
$this->assertEquals('/path%20test/info', $request->getPathInfo());
|
||||
}
|
||||
|
||||
public function testGetPreferredLanguage()
|
||||
@ -946,6 +939,100 @@ class RequestTest extends \PHPUnit_Framework_TestCase
|
||||
Request::trustProxyData();
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider getBaseUrlData
|
||||
*/
|
||||
public function testGetBaseUrl($uri, $server, $expectedBaseUrl, $expectedPathInfo)
|
||||
{
|
||||
$request = Request::create($uri, 'GET', array(), array(), array(), $server);
|
||||
|
||||
$this->assertSame($expectedBaseUrl, $request->getBaseUrl(), 'baseUrl');
|
||||
$this->assertSame($expectedPathInfo, $request->getPathInfo(), 'pathInfo');
|
||||
}
|
||||
|
||||
public function getBaseUrlData()
|
||||
{
|
||||
return array(
|
||||
array(
|
||||
'/foo%20bar',
|
||||
array(
|
||||
'SCRIPT_FILENAME' => '/home/John Doe/public_html/foo bar/app.php',
|
||||
'SCRIPT_NAME' => '/foo bar/app.php',
|
||||
'PHP_SELF' => '/foo bar/app.php',
|
||||
),
|
||||
'/foo%20bar',
|
||||
'/',
|
||||
),
|
||||
array(
|
||||
'/foo%20bar/home',
|
||||
array(
|
||||
'SCRIPT_FILENAME' => '/home/John Doe/public_html/foo bar/app.php',
|
||||
'SCRIPT_NAME' => '/foo bar/app.php',
|
||||
'PHP_SELF' => '/foo bar/app.php',
|
||||
),
|
||||
'/foo%20bar',
|
||||
'/home',
|
||||
),
|
||||
array(
|
||||
'/foo%20bar/app.php/home',
|
||||
array(
|
||||
'SCRIPT_FILENAME' => '/home/John Doe/public_html/foo bar/app.php',
|
||||
'SCRIPT_NAME' => '/foo bar/app.php',
|
||||
'PHP_SELF' => '/foo bar/app.php',
|
||||
),
|
||||
'/foo%20bar/app.php',
|
||||
'/home',
|
||||
),
|
||||
array(
|
||||
'/foo%20bar/app.php/home%2Fbaz',
|
||||
array(
|
||||
'SCRIPT_FILENAME' => '/home/John Doe/public_html/foo bar/app.php',
|
||||
'SCRIPT_NAME' => '/foo bar/app.php',
|
||||
'PHP_SELF' => '/foo bar/app.php',
|
||||
),
|
||||
'/foo%20bar/app.php',
|
||||
'/home%2Fbaz',
|
||||
),
|
||||
array(
|
||||
'/foo/bar+baz',
|
||||
array(
|
||||
'SCRIPT_FILENAME' => '/home/John Doe/public_html/foo/app.php',
|
||||
'SCRIPT_NAME' => '/foo/app.php',
|
||||
'PHP_SELF' => '/foo/app.php',
|
||||
),
|
||||
'/foo',
|
||||
'/bar+baz',
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider urlencodedStringPrefixData
|
||||
*/
|
||||
public function testUrlencodedStringPrefix($string, $prefix, $expect)
|
||||
{
|
||||
$request = new Request;
|
||||
|
||||
$me = new \ReflectionMethod($request, 'getUrlencodedPrefix');
|
||||
$me->setAccessible(true);
|
||||
|
||||
$this->assertSame($expect, $me->invoke($request, $string, $prefix));
|
||||
}
|
||||
|
||||
public function urlencodedStringPrefixData()
|
||||
{
|
||||
return array(
|
||||
array('foo', 'foo', 'foo'),
|
||||
array('fo%6f', 'foo', 'fo%6f'),
|
||||
array('foo/bar', 'foo', 'foo'),
|
||||
array('fo%6f/bar', 'foo', 'fo%6f'),
|
||||
array('f%6f%6f/bar', 'foo', 'f%6f%6f'),
|
||||
array('%66%6F%6F/bar', 'foo', '%66%6F%6F'),
|
||||
array('fo+o/bar', 'fo+o', 'fo+o'),
|
||||
array('fo%2Bo/bar', 'fo+o', 'fo%2Bo'),
|
||||
);
|
||||
}
|
||||
|
||||
private function stopTrustingProxyData()
|
||||
{
|
||||
$class = new \ReflectionClass('Symfony\\Component\\HttpFoundation\\Request');
|
||||
|
Reference in New Issue
Block a user