--- tests/Zend/Controller/Request/HttpTest.php (revision 23514) +++ tests/Zend/Controller/Request/HttpTest.php (working copy) @@ -951,6 +951,31 @@ } /** + * @group ZF-3527 + */ + public function testPathInfoShouldNotDecodeRequestParams() + { + $request = new Zend_Controller_Request_Http(); + $_SERVER['REQUEST_URI'] = '/module/controller/action/param/escaped%2Fstring'; + $pathInfo = $request->getPathInfo(); + + $this->assertEquals( '/module/controller/action/param/escaped%2Fstring', $pathInfo, $pathInfo); + } + + /** + * @group ZF-3527 + */ + public function testPathInfoShouldNotDecodeRequestParamsOnlyUrlBase() + { + $request = new Zend_Controller_Request_Http(); + $request->setBaseUrl( '%7Euser' ); + $_SERVER['REQUEST_URI'] = '~user/module/controller/action/param/escaped%2Fstring'; + $pathInfo = $request->getPathInfo(); + + $this->assertEquals( '/module/controller/action/param/escaped%2Fstring', $pathInfo, $pathInfo); + } + + /** * @group ZF-9899 */ public function testHostNameShouldBeEmpty() Index: library/Zend/Controller/Request/Http.php =================================================================== --- library/Zend/Controller/Request/Http.php (revision 23514) +++ library/Zend/Controller/Request/Http.php (working copy) @@ -623,17 +623,26 @@ $requestUri = substr($requestUri, 0, $pos); } - $requestUri = urldecode($requestUri); + $requestUriDecoded = urldecode($requestUri); if (null !== $baseUrl - && ((!empty($baseUrl) && 0 === strpos($requestUri, $baseUrl)) - || empty($baseUrl)) - && false === ($pathInfo = substr($requestUri, strlen($baseUrl))) + && ( !empty($baseUrl) && 0 === strpos($requestUriDecoded, $baseUrl) ) ){ - // If substr() returns false then PATH_INFO is set to an empty string - $pathInfo = ''; - } elseif (null === $baseUrl - || (!empty($baseUrl) && false === strpos($requestUri, $baseUrl)) + // try to find out which part is encoded + if (0 === strpos($requestUri, $this->_baseUrl)) { + // both parts don't need encoding + $pathInfo = substr($requestUri, strlen($this->_baseUrl)); + } elseif (0 === strpos($requestUriDecoded, $this->_baseUrl)) { + // request_uri needs encoding for match + $pathInfo = substr($requestUri, strlen(urlencode($this->_baseUrl))); + } elseif (0 === strpos($requestUri, $baseUrl)) { + // base_url need encoding for match + $pathInfo = substr($requestUri, strlen(urldecode($this->_baseUrl))); + } else { + $pathInfo = ''; + } + } elseif (null === $baseUrl || empty($baseUrl) + || (!empty($baseUrl) && false === strpos($requestUriDecoded, $baseUrl)) ) { $pathInfo = $requestUri; }