FIX Director::is_absolute_url() now ignores query and fragment strings

Director::is_absolute_url() checks for //. It used to include the
entire URI, now it ignores the query and fragment strings.
This commit is contained in:
Simon Welsh 2012-06-29 17:14:28 +12:00
parent 23ed5335e6
commit e0505406a7
2 changed files with 24 additions and 16 deletions

View File

@ -548,7 +548,15 @@ class Director implements TemplateGlobalProvider {
* @return boolean * @return boolean
*/ */
public static function is_absolute_url($url) { public static function is_absolute_url($url) {
// Strip off the query and fragment parts of the URL before checking
if(($queryPosition = strpos($url, '?')) !== false) {
$url = substr($url, 0, $queryPosition-1);
}
if(($hashPosition = strpos($url, '#')) !== false) {
$url = substr($url, 0, $hashPosition-1);
}
$colonPosition = strpos($url, ':'); $colonPosition = strpos($url, ':');
$slashPosition = strpos($url, '/');
return ( return (
// Base check for existence of a host on a compliant URL // Base check for existence of a host on a compliant URL
parse_url($url, PHP_URL_HOST) parse_url($url, PHP_URL_HOST)
@ -558,13 +566,10 @@ class Director implements TemplateGlobalProvider {
|| preg_match('/\s*[\/]{2,}/', $url) || preg_match('/\s*[\/]{2,}/', $url)
|| ( || (
// If a colon is found, check if it's part of a valid scheme definition // If a colon is found, check if it's part of a valid scheme definition
// (meaning its not preceded by a slash, hash or questionmark). // (meaning its not preceded by a slash).
// URLs in query parameters are assumed to be correctly urlencoded based on RFC3986,
// in which case no colon should be present in the parameters.
$colonPosition !== FALSE $colonPosition !== FALSE
&& !preg_match('![/?#]!', substr($url, 0, $colonPosition)) && ($slashPosition === FALSE || $colonPosition < $slashPosition)
) )
); );
} }

View File

@ -98,6 +98,8 @@ class DirectorTest extends SapphireTest {
$this->assertFalse(Director::is_absolute_url('test.com/testpage')); $this->assertFalse(Director::is_absolute_url('test.com/testpage'));
$this->assertFalse(Director::is_absolute_url('/relative')); $this->assertFalse(Director::is_absolute_url('/relative'));
$this->assertFalse(Director::is_absolute_url('relative')); $this->assertFalse(Director::is_absolute_url('relative'));
$this->assertFalse(Director::is_absolute_url("/relative/?url=http://foo.com"));
$this->assertFalse(Director::is_absolute_url("/relative/#http://foo.com"));
$this->assertTrue(Director::is_absolute_url("https://test.com/?url=http://foo.com")); $this->assertTrue(Director::is_absolute_url("https://test.com/?url=http://foo.com"));
$this->assertTrue(Director::is_absolute_url("trickparseurl:http://test.com")); $this->assertTrue(Director::is_absolute_url("trickparseurl:http://test.com"));
$this->assertTrue(Director::is_absolute_url('//test.com')); $this->assertTrue(Director::is_absolute_url('//test.com'));
@ -116,7 +118,8 @@ class DirectorTest extends SapphireTest {
$this->assertFalse(Director::is_relative_url('ftp://test.com')); $this->assertFalse(Director::is_relative_url('ftp://test.com'));
$this->assertTrue(Director::is_relative_url('/relative')); $this->assertTrue(Director::is_relative_url('/relative'));
$this->assertTrue(Director::is_relative_url('relative')); $this->assertTrue(Director::is_relative_url('relative'));
// $this->assertTrue(Director::is_relative_url('/relative/?url=http://test.com')); $this->assertTrue(Director::is_relative_url('/relative/?url=http://test.com'));
$this->assertTrue(Director::is_relative_url('/relative/#=http://test.com'));
} }
public function testMakeRelative() { public function testMakeRelative() {