[BUGFIX] Ignore PATH_INFO in NormalizedParams scriptName calculation 19/60719/8
authorBenjamin Franzke <bfr@qbus.de>
Thu, 9 May 2019 10:22:58 +0000 (12:22 +0200)
committerBenni Mack <benni@typo3.org>
Mon, 13 May 2019 04:12:22 +0000 (06:12 +0200)
When NormalizedParams was introduced, the code that was refactored from
GeneralUtility:getIndpEnv did not take into account that PATH_INFO
could be set, but be empty. (which happens with the Debian 9 NGINX
default configuration which uses `fastcgi_split_path_info` and set's
`fastcgi_param PATH_INFO` even if it's empty).

Now, the fallback to PATH_INFO has been introduced with
the initial revision of TYPO3 and isn't needed at all nowadays,
it's actually wrong, as a REQUEST_URI to /index.php/foo/bar
would incorrectly be interpreted as $scriptName == "/foo/bar".

This patch additionally replaces PATH_INFO with SCRIPT_NAME in
test cases where this variable is actually wrong (we assume test cases
have been modeled to match (old) code, instead of reality here):

 * ProxyPass does not result in PATH_INFO being set,
   it's SCRIPT_NAME here.
 * PATH_INFO is not set for regular request
   to /typo3/index.php

Resolves: #88304
Releases: master, 9.5
Change-Id: I501ad3bc10b0988385906a1fe9cb668c5e3696b6
Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/60719
Tested-by: TYPO3com <noreply@typo3.com>
Tested-by: Benny Schimmer <b.schimmer@saint-elmos.com>
Tested-by: Andreas Fernandez <a.fernandez@scripting-base.de>
Tested-by: Benni Mack <benni@typo3.org>
Reviewed-by: Benny Schimmer <b.schimmer@saint-elmos.com>
Reviewed-by: Andreas Fernandez <a.fernandez@scripting-base.de>
Reviewed-by: Markus Klein <markus.klein@typo3.org>
Reviewed-by: Benni Mack <benni@typo3.org>
typo3/sysext/core/Classes/Http/NormalizedParams.php
typo3/sysext/core/Classes/Routing/PageRouter.php
typo3/sysext/core/Tests/Unit/Http/NormalizedParamsTest.php

index be36a69..2667672 100644 (file)
@@ -609,11 +609,7 @@ class NormalizedParams
      */
     protected static function determineScriptName(array $serverParams, array $configuration, bool $isHttps, bool $isBehindReverseProxy): string
     {
-        $scriptName = $serverParams['ORIG_PATH_INFO'] ??
-            $serverParams['PATH_INFO'] ??
-            $serverParams['ORIG_SCRIPT_NAME'] ??
-            $serverParams['SCRIPT_NAME'] ??
-            '';
+        $scriptName = ($serverParams['ORIG_SCRIPT_NAME'] ?? '') ?: ($serverParams['SCRIPT_NAME'] ?? '');
         if ($isBehindReverseProxy) {
             // Add a prefix if TYPO3 is behind a proxy: ext-domain.com => int-server.com/prefix
             if ($isHttps && !empty($configuration['reverseProxyPrefixSSL'])) {
index 5b63df2..ecc1278 100644 (file)
@@ -123,7 +123,7 @@ class PageRouter implements RouterInterface
             $normalizedParams = $request->getAttribute('normalizedParams');
             if ($normalizedParams instanceof NormalizedParams) {
                 $scriptName = ltrim($normalizedParams->getScriptName(), '/');
-                if (strpos($urlPath, $scriptName) !== false) {
+                if ($scriptName !== '' && strpos($urlPath, $scriptName) !== false) {
                     $urlPath = str_replace($scriptName, '', $urlPath);
                 }
             }
index 1de5384..3863175 100644 (file)
@@ -355,24 +355,62 @@ class NormalizedParamsTest extends UnitTestCase
                 [],
                 ''
             ],
-            'use ORIG_PATH_INFO' => [
+            'use ORIG_SCRIPT_NAME if ORIG_PATH_INFO is set but empty' => [
                 [
-                    'ORIG_PATH_INFO' => '/orig/path/info.php',
-                    'PATH_INFO' => '/path/info.php',
+                    'ORIG_PATH_INFO' => '',
+                    'PATH_INFO' => '',
                     'ORIG_SCRIPT_NAME' => '/orig/script/name.php',
                     'SCRIPT_NAME' => '/script/name.php',
                 ],
                 [],
-                '/orig/path/info.php',
+                '/orig/script/name.php',
             ],
-            'use PATH_INFO' => [
+            'use ORIG_SCRIPT_NAME if PATH_INFO is set but empty' => [
                 [
-                    'PATH_INFO' => '/path/info.php',
+                    'PATH_INFO' => '',
                     'ORIG_SCRIPT_NAME' => '/orig/script/name.php',
                     'SCRIPT_NAME' => '/script/name.php',
                 ],
                 [],
-                '/path/info.php',
+                '/orig/script/name.php',
+            ],
+            'use SCRIPT_NAME if ORIG_PATH_INFO is set but empty' => [
+                [
+                    'ORIG_PATH_INFO' => '',
+                    'PATH_INFO' => '',
+                    'ORIG_SCRIPT_NAME' => '',
+                    'SCRIPT_NAME' => '/script/name.php',
+                ],
+                [],
+                '/script/name.php',
+            ],
+            'use SCRIPT_NAME if PATH_INFO is set but empty' => [
+                [
+                    'PATH_INFO' => '',
+                    'ORIG_SCRIPT_NAME' => '',
+                    'SCRIPT_NAME' => '/script/name.php',
+                ],
+                [],
+                '/script/name.php',
+            ],
+            'use SCRIPT_NAME if ORIG_PATH_INFO is set' => [
+                [
+                    'ORIG_PATH_INFO' => '/foo/bar',
+                    'PATH_INFO' => '',
+                    'ORIG_SCRIPT_NAME' => '',
+                    'SCRIPT_NAME' => '/script/name.php',
+                ],
+                [],
+                '/script/name.php',
+            ],
+            'use SCRIPT_NAME if PATH_INFO is set' => [
+                [
+                    'PATH_INFO' => '/foo/bar',
+                    'ORIG_SCRIPT_NAME' => '',
+                    'SCRIPT_NAME' => '/script/name.php',
+                ],
+                [],
+                '/script/name.php',
             ],
             'use ORIG_SCRIPT_NAME' => [
                 [
@@ -393,7 +431,7 @@ class NormalizedParamsTest extends UnitTestCase
                 [
                     'REMOTE_ADDR' => '123.123.123.123',
                     'HTTPS' => 'on',
-                    'PATH_INFO' => '/path/info.php',
+                    'SCRIPT_NAME' => '/path/info.php',
                 ],
                 [
                     'reverseProxyIP' => '123.123.123.123',
@@ -404,7 +442,7 @@ class NormalizedParamsTest extends UnitTestCase
             'add proxy prefix' => [
                 [
                     'REMOTE_ADDR' => '123.123.123.123',
-                    'PATH_INFO' => '/path/info.php',
+                    'SCRIPT_NAME' => '/path/info.php',
                 ],
                 [
                     'reverseProxyIP' => '123.123.123.123',
@@ -562,7 +600,7 @@ class NormalizedParamsTest extends UnitTestCase
     {
         $serverParams = [
             'HTTP_HOST' => 'www.domain.com',
-            'PATH_INFO' => '/typo3/index.php',
+            'SCRIPT_NAME' => '/typo3/index.php',
         ];
         $expected = 'http://www.domain.com/typo3/index.php';
         $serverRequestParameters = new NormalizedParams($serverParams, [], '', '');
@@ -576,7 +614,7 @@ class NormalizedParamsTest extends UnitTestCase
     {
         $serverParams = [
             'HTTP_HOST' => 'www.domain.com',
-            'PATH_INFO' => '/typo3/index.php',
+            'SCRIPT_NAME' => '/typo3/index.php',
         ];
         $expected = 'http://www.domain.com/typo3/';
         $serverRequestParameters = new NormalizedParams($serverParams, [], '', '');