From 36b36da6d1262fe3cf2bbe7c33a556954ea07bab Mon Sep 17 00:00:00 2001 From: Alexander Ebert Date: Fri, 20 Feb 2015 17:57:10 +0100 Subject: [PATCH] Improved handling of aliased/mistyped controllers --- .../system/request/FlexibleRoute.class.php | 8 +++- .../system/request/RequestHandler.class.php | 43 +++++++++++++++++-- 2 files changed, 46 insertions(+), 5 deletions(-) diff --git a/wcfsetup/install/files/lib/system/request/FlexibleRoute.class.php b/wcfsetup/install/files/lib/system/request/FlexibleRoute.class.php index 81f433239f..3a6209d3f0 100644 --- a/wcfsetup/install/files/lib/system/request/FlexibleRoute.class.php +++ b/wcfsetup/install/files/lib/system/request/FlexibleRoute.class.php @@ -67,7 +67,11 @@ class FlexibleRoute implements IRoute { (?P[A-Za-z0-9\-]+) (?: / - (?P\d+) + (?P\d+) + (?: + - + (?P[^/]+) + )? )? )? ~x'; @@ -282,7 +286,7 @@ class FlexibleRoute implements IRoute { $controllerName .= strtolower($parts[$i]); } - $alias = RequestHandler::getInstance()->getAliasByController($controllerName); + $alias = (!$this->isACP) ? RequestHandler::getInstance()->getAliasByController($controllerName) : null; self::$controllerNames[$controller] = ($alias) ?: $controllerName; } diff --git a/wcfsetup/install/files/lib/system/request/RequestHandler.class.php b/wcfsetup/install/files/lib/system/request/RequestHandler.class.php index b0d223d4ee..81d3da3b92 100644 --- a/wcfsetup/install/files/lib/system/request/RequestHandler.class.php +++ b/wcfsetup/install/files/lib/system/request/RequestHandler.class.php @@ -179,9 +179,10 @@ class RequestHandler extends SingletonFactory { // handle controller aliasing if (!URL_LEGACY_MODE && isset($routeData['controller'])) { - // aliased controller, pretend it does not exist - if ($this->getAliasByController($routeData['controller']) !== null) { - throw new IllegalLinkException(); + // aliased controller, redirect to new URL + $alias = $this->getAliasByController($routeData['controller']); + if ($alias !== null) { + $this->redirect($routeData, $application); } $controller = $this->getControllerByAlias($routeData['controller']); @@ -222,6 +223,19 @@ class RequestHandler extends SingletonFactory { throw new SystemException("unable to find class '".$classData['className']."'"); } + // check if controller was provided exactly as it should + if (!URL_LEGACY_MODE && !$this->isACPRequest()) { + if (preg_match('~([A-Za-z0-9]+)(?:Action|Form|Page)$~', $classData['className'], $matches)) { + $parts = preg_split('~([A-Z][a-z0-9]+)~', $matches[1], null, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY); + $parts = array_map('strtolower', $parts); + $realController = implode('-', $parts); + + if ($controller != $realController) { + $this->redirect($routeData, $application, $matches[1]); + } + } + } + $this->activeRequest = new Request($classData['className'], $classData['controller'], $classData['pageType']); } catch (SystemException $e) { @@ -229,6 +243,29 @@ class RequestHandler extends SingletonFactory { } } + /** + * Redirects to the actual URL, e.g. controller has been aliased or mistyped (boardlist instead of board-list). + * + * @param array<string> $routeData + * @param string $application + * @param string $controller + */ + protected function redirect(array $routeData, $application, $controller = null) { + $routeData['application'] = $application; + if ($controller !== null) $routeData['controller'] = $controller; + + // append the remaining query parameters + foreach ($_GET as $key => $value) { + if (!empty($value)) { + $linkData[$key] = $value; + } + } + + $redirectURL = LinkHandler::getInstance()->getLink($routeData['controller'], $linkData); + HeaderUtil::redirect($redirectURL, true); + exit; + } + /** * Checks page access for possible mandatory redirects. * -- 2.20.1