Issues

ZF-9091: Zend_Controller_Request_Http::setPathInfo setting path info to wrong string if base url doesnt exist in request uri

Description

The code is doing a substr on the request uri with the length of the base url without actually checking if the base url is in the request uri. This can cause issues with it not finding either the module or the controller.

e.g. If the request uri is set to /auth/login and the index.php is located at /app/index.php then the base url is set to '/app'. In this case the path info is set to 'h/login' rather than '/auth/login' which is quite clearly wrong as we're not looking for a controller/module 'h', we're looking for auth.

The following code (line 626 in file Zend/Controller/Request/Http.php):

if ((null !== $baseUrl) && (false === ($pathInfo = substr($requestUri, strlen($baseUrl))))) { // If substr() returns false then PATH_INFO is set to an empty string $pathInfo = ''; } elseif (null === $baseUrl) { $pathInfo = $requestUri; }

Needs changing to:

if (null !== $baseUrl && ((!empty($baseUrl) && 0 === strpos($requestUri, $baseUrl)) || empty($baseUrl)) && false === ($pathInfo = substr($requestUri, strlen($baseUrl)))) { // If substr() returns false then PATH_INFO is set to an empty string $pathInfo = ''; } elseif (null === $baseUrl || (!empty($baseUrl) && false === strpos($requestUri, $baseUrl))) { $pathInfo = $requestUri; }

or something similar to deal with this kind of situation. This case is encountered when doing some rewrites of the url via apache (or other webserver software) before using the framework application.

Comments

Can you provide a reproducible test case, please?

in the .htaccess file in the webroot of the current folder we have the following:

RewriteEngine on RewriteCond %{REQUEST_FILENAME} -s [OR] RewriteCond %{REQUEST_FILENAME} -l [OR] RewriteCond %{REQUEST_FILENAME} -d RewriteRule ^.$ - [NC,L] RewriteRule ^.$ /app/index.php [NC,L]

redirecting any requests for files that don't exist through the new Zend Framework application's webroot (the Apache alias "/app").

So in the case of someone requesting via a url:

http://testdomain.com/index/index

this is obviously re-written via apache to:

http://testdomain.com/app/index/index

however, php is seeing the request uri as "/index/index" not "/app/index/index" because it is coming directly from the browser's request.

This means when it gets to the above mentioned code it is removing a sub-string of the length of "/app" from "/index/index" producing "ex/index" as the path info, obviously removing "/ind" even though this isn't the same as the base url "/app"

The same occurs, as mentioned above, with request uri "/auth/login" with it removing "/aut" therefore producing "h/login" as the path info

I've tested the new code provided above with our separate web-sites that run from from other base URLs and it seems to run correctly from those.

Fixed in trunk and 1.10 release branch. Thanks for providing the extra information -- I was able to create a reproduce case from that.

Many Thanks, glad to help