From 4a7aef0e25c2d7224b2ff265684360dc7bfefdc4 Mon Sep 17 00:00:00 2001 From: Hamish Friedlander Date: Mon, 19 Aug 2013 11:35:34 +1200 Subject: [PATCH] FIX Double slashes in ParameterConfirmationToken --- core/startup/ParameterConfirmationToken.php | 25 +++++++-- .../ParameterConfirmationTokenTest.php | 51 +++++++++++++++++++ 2 files changed, 71 insertions(+), 5 deletions(-) create mode 100644 tests/core/startup/ParameterConfirmationTokenTest.php diff --git a/core/startup/ParameterConfirmationToken.php b/core/startup/ParameterConfirmationToken.php index 288488b6b..081b3d664 100644 --- a/core/startup/ParameterConfirmationToken.php +++ b/core/startup/ParameterConfirmationToken.php @@ -70,7 +70,10 @@ class ParameterConfirmationToken { ); } - public function reloadWithToken() { + /** What to use instead of BASE_URL. Must not contain protocol or host. @var string */ + static public $alternateBaseURL = null; + + protected function currentAbsoluteURL() { global $url; // Are we http or https? @@ -83,15 +86,27 @@ class ParameterConfirmationToken { if((!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off')) $proto = 'https'; if(isset($_SERVER['SSL'])) $proto = 'https'; - // What's our host - $host = $_SERVER['HTTP_HOST']; + $parts = array_filter(array( + // What's our host + $_SERVER['HTTP_HOST'], + // SilverStripe base + self::$alternateBaseURL !== null ? self::$alternateBaseURL : BASE_URL, + // And URL + $url + )); + + // Join together with protocol into our current absolute URL, avoiding duplicated "/" characters + return "$proto://" . preg_replace('#/{2,}#', '/', implode('/', $parts)); + } + + public function reloadWithToken() { + $location = $this->currentAbsoluteURL(); // What's our GET params (ensuring they include the original parameter + a new token) $params = array_merge($_GET, $this->params()); unset($params['url']); - // Join them all together into the original URL - $location = "$proto://" . $host . '/' . ltrim(BASE_URL, '/') . $url . ($params ? '?'.http_build_query($params) : ''); + if ($params) $location .= '?'.http_build_query($params); // And redirect if (headers_sent()) { diff --git a/tests/core/startup/ParameterConfirmationTokenTest.php b/tests/core/startup/ParameterConfirmationTokenTest.php new file mode 100644 index 000000000..ad0795598 --- /dev/null +++ b/tests/core/startup/ParameterConfirmationTokenTest.php @@ -0,0 +1,51 @@ +addPart(array(), '', $host); + + foreach(array('', '/', 'bar', 'bar/', '/bar', '/bar/') as $base) { + list($baseAnswer, $baseSlash) = $this->addPart($hostAnswer, $hostSlash, $base); + + foreach(array('', '/', 'baz', 'baz/', '/baz', '/baz/') as $url) { + list($urlAnswer, $urlSlash) = $this->addPart($baseAnswer, $baseSlash, $url); + + $_SERVER['HTTP_HOST'] = $host; + ParameterConfirmationToken::$alternateBaseURL = $base; + + $this->assertEquals('http://'.implode('/', $urlAnswer) . $urlSlash, $token->currentAbsoluteURL()); + } + } + } + } + +} \ No newline at end of file