ZF-5533: Zend_Controller_Router_Route_Module fails to work when request url contains capital letters
Description
h1. Replicating the Error
Set up a Zend Framework application that contains 2 modules: default and admin Controller directories are setup via the front controller's addModuleDirectory() function No custom routing is used, instead rely on ZF's module routing
h2. What works:
http://hostname/index/index correctly routes to the default module's IndexController and IndexAction http://hostname/INDEX/index correctly routes to the default module's IndexController and IndexAction http://hostname/bob/index/ correctly generates an error of type EXCEPTION_NO_CONTROLLER in the error handler plugin http://hostname/admin/index/index correctly routes to the admin module's IndexController and IndexAction
h2. What doesn't work:
http://hostname/ADMIN/index/index incorrectly generates an error of type EXCEPTION_NO_CONTROLLER in the error handler
Further, if notices are set to display, then Zend/Controller/Dispatcher/Standard.php generates a notice on line 373:
h1. What's wrong
Zend/Controller/Dispatcher/Standard.php stores the module names in all lower case in the _controllerDirs array, but multiple functions access the _controllerDirs array with the unformatted module string (which may have capital letters in it). The formatModuleName function is not used in these function, but the formatModuleName also formats modules to have a uppercase first letter.
_This is what will happen:_
The dispatcher's isValidModule function correctly implements strtolower() to check if it is a valid module, but Zend/Controller/Dispatcher/Standard.php in getControllerClass() calls isValidModule() and then tries to access the controllerDirs array with the unformatted module name on line 373, generating the unexpected notice of a non-valid array index.
Since "ADMIN" is not a valid index of the controllerDirs directory, _curDirectory remains uninitialized, the isDispatchable function returns false and the "Invalid controller specified" exception is thrown.
Further, If the getControllerClass() function is fixed, the viewRenderer will fail when calling getControllerDirectory.
h1. Minimum required changes to fix this bug:
getControllerDirectory() of Zend_Controller_Dispatcher_Standard (called by the viewRenderer)
127 $module = (string) $module; to 127 $module = strtolower($module);
and
getControllerClass() of Zend_Controller_Dispatcher_Standard
373 $this->_curDirectory = $controllerDirs[$module]; to 373 $this->_curDirectory = $controllerDirs[strtolower($module)];```
Comments
Posted by Adam Lundrigan (adamlundrigan) on 2011-11-15T02:46:53.000+0000
What are the possible backwards-compatibility side-effects to implementing this change? Can it be safely done at this stage without breaking existing implementations?