Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit d17ba0e

Browse files
arnaud-lbvicb
authored andcommitted
Fixed base URL detection when request URI contains encoded chars
Signed-off-by: Victor Berchet <[email protected]>
1 parent 127cff0 commit d17ba0e

File tree

2 files changed

+126
-15
lines changed

2 files changed

+126
-15
lines changed

src/Symfony/Component/HttpFoundation/Request.php

Lines changed: 31 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1301,14 +1301,14 @@ protected function prepareBaseUrl()
13011301
// Does the baseUrl have anything in common with the request_uri?
13021302
$requestUri = $this->getRequestUri();
13031303

1304-
if ($baseUrl && 0 === strpos($requestUri, $baseUrl)) {
1304+
if ($baseUrl && false !== $prefix = $this->getUrlencodedPrefix($requestUri, $baseUrl)) {
13051305
// full $baseUrl matches
1306-
return $baseUrl;
1306+
return $prefix;
13071307
}
13081308

1309-
if ($baseUrl && 0 === strpos($requestUri, dirname($baseUrl))) {
1309+
if ($baseUrl && false !== $prefix = $this->getUrlencodedPrefix($requestUri, dirname($baseUrl))) {
13101310
// directory portion of $baseUrl matches
1311-
return rtrim(dirname($baseUrl), '/');
1311+
return rtrim($prefix, '/');
13121312
}
13131313

13141314
$truncatedRequestUri = $requestUri;
@@ -1317,7 +1317,7 @@ protected function prepareBaseUrl()
13171317
}
13181318

13191319
$basename = basename($baseUrl);
1320-
if (empty($basename) || !strpos($truncatedRequestUri, $basename)) {
1320+
if (empty($basename) || !strpos(urldecode($truncatedRequestUri), $basename)) {
13211321
// no match whatsoever; set it blank
13221322
return '';
13231323
}
@@ -1378,14 +1378,14 @@ protected function preparePathInfo()
13781378
$requestUri = substr($requestUri, 0, $pos);
13791379
}
13801380

1381-
if ((null !== $baseUrl) && (false === ($pathInfo = substr(urldecode($requestUri), strlen(urldecode($baseUrl)))))) {
1381+
if ((null !== $baseUrl) && (false === ($pathInfo = substr($requestUri, strlen($baseUrl))))) {
13821382
// If substr() returns false then PATH_INFO is set to an empty string
13831383
return '/';
13841384
} elseif (null === $baseUrl) {
13851385
return $requestUri;
13861386
}
13871387

1388-
return (string) $pathInfo;
1388+
return rawurldecode((string) $pathInfo);
13891389
}
13901390

13911391
/**
@@ -1423,4 +1423,28 @@ private function setPhpDefaultLocale($locale)
14231423
} catch (\Exception $e) {
14241424
}
14251425
}
1426+
1427+
/*
1428+
* Returns the prefix as encoded in the string when the string starts with
1429+
* the given prefix, false otherwise.
1430+
*
1431+
* @param string $string The urlencoded string
1432+
* @param string $prefix The prefix not encoded
1433+
*
1434+
* @return string|false The prefix as it is encoded in $string, or false
1435+
*/
1436+
private function getUrlencodedPrefix($string, $prefix)
1437+
{
1438+
if (0 !== strpos(rawurldecode($string), $prefix)) {
1439+
return false;
1440+
}
1441+
1442+
$len = strlen($prefix);
1443+
1444+
if (preg_match("#^(%[[:xdigit:]]{2}|.){{$len}}#", $string, $match)) {
1445+
return $match[0];
1446+
}
1447+
1448+
return false;
1449+
}
14261450
}

src/Symfony/Component/HttpFoundation/Tests/RequestTest.php

Lines changed: 95 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -751,18 +751,11 @@ public function testGetPathInfo()
751751

752752
$this->assertEquals('/path/info', $request->getPathInfo());
753753

754-
$server = array();
755-
$server['REQUEST_URI'] = '/path test/info';
756-
$request->initialize(array(), array(), array(), array(), array(), $server);
757-
758-
$this->assertEquals('/path test/info', $request->getPathInfo());
759-
760754
$server = array();
761755
$server['REQUEST_URI'] = '/path%20test/info';
762756
$request->initialize(array(), array(), array(), array(), array(), $server);
763757

764-
$this->assertEquals('/path test/info', $request->getPathInfo());
765-
758+
$this->assertEquals('/path%20test/info', $request->getPathInfo());
766759
}
767760

768761
public function testGetPreferredLanguage()
@@ -946,6 +939,100 @@ private function startTrustingProxyData()
946939
Request::trustProxyData();
947940
}
948941

942+
/**
943+
* @dataProvider getBaseUrlData
944+
*/
945+
public function testGetBaseUrl($uri, $server, $expectedBaseUrl, $expectedPathInfo)
946+
{
947+
$request = Request::create($uri, 'GET', array(), array(), array(), $server);
948+
949+
$this->assertSame($expectedBaseUrl, $request->getBaseUrl(), 'baseUrl');
950+
$this->assertSame($expectedPathInfo, $request->getPathInfo(), 'pathInfo');
951+
}
952+
953+
public function getBaseUrlData()
954+
{
955+
return array(
956+
array(
957+
'/foo%20bar',
958+
array(
959+
'SCRIPT_FILENAME' => '/home/John Doe/public_html/foo bar/app.php',
960+
'SCRIPT_NAME' => '/foo bar/app.php',
961+
'PHP_SELF' => '/foo bar/app.php',
962+
),
963+
'/foo%20bar',
964+
'/',
965+
),
966+
array(
967+
'/foo%20bar/home',
968+
array(
969+
'SCRIPT_FILENAME' => '/home/John Doe/public_html/foo bar/app.php',
970+
'SCRIPT_NAME' => '/foo bar/app.php',
971+
'PHP_SELF' => '/foo bar/app.php',
972+
),
973+
'/foo%20bar',
974+
'/home',
975+
),
976+
array(
977+
'/foo%20bar/app.php/home',
978+
array(
979+
'SCRIPT_FILENAME' => '/home/John Doe/public_html/foo bar/app.php',
980+
'SCRIPT_NAME' => '/foo bar/app.php',
981+
'PHP_SELF' => '/foo bar/app.php',
982+
),
983+
'/foo%20bar/app.php',
984+
'/home',
985+
),
986+
array(
987+
'/foo%20bar/app.php/home%2Fbaz',
988+
array(
989+
'SCRIPT_FILENAME' => '/home/John Doe/public_html/foo bar/app.php',
990+
'SCRIPT_NAME' => '/foo bar/app.php',
991+
'PHP_SELF' => '/foo bar/app.php',
992+
),
993+
'/foo%20bar/app.php',
994+
'/home%2Fbaz',
995+
),
996+
array(
997+
'/foo/bar+baz',
998+
array(
999+
'SCRIPT_FILENAME' => '/home/John Doe/public_html/foo/app.php',
1000+
'SCRIPT_NAME' => '/foo/app.php',
1001+
'PHP_SELF' => '/foo/app.php',
1002+
),
1003+
'/foo',
1004+
'/bar+baz',
1005+
),
1006+
);
1007+
}
1008+
1009+
/**
1010+
* @dataProvider urlencodedStringPrefixData
1011+
*/
1012+
public function testUrlencodedStringPrefix($string, $prefix, $expect)
1013+
{
1014+
$request = new Request;
1015+
1016+
$me = new \ReflectionMethod($request, 'getUrlencodedPrefix');
1017+
$me->setAccessible(true);
1018+
1019+
$this->assertSame($expect, $me->invoke($request, $string, $prefix));
1020+
}
1021+
1022+
public function urlencodedStringPrefixData()
1023+
{
1024+
return array(
1025+
array('foo', 'foo', 'foo'),
1026+
array('fo%6f', 'foo', 'fo%6f'),
1027+
array('foo/bar', 'foo', 'foo'),
1028+
array('fo%6f/bar', 'foo', 'fo%6f'),
1029+
array('f%6f%6f/bar', 'foo', 'f%6f%6f'),
1030+
array('%66%6F%6F/bar', 'foo', '%66%6F%6F'),
1031+
array('fo+o/bar', 'fo+o', 'fo+o'),
1032+
array('fo%2Bo/bar', 'fo+o', 'fo%2Bo'),
1033+
);
1034+
}
1035+
9491036
private function stopTrustingProxyData()
9501037
{
9511038
$class = new \ReflectionClass('Symfony\\Component\\HttpFoundation\\Request');

0 commit comments

Comments
 (0)