[BUGFIX] AddQueryStringMethod overwrites parameters 11/25211/6
authorKlaas Johan Kooistra <k.kooistra@drecomm.nl>
Fri, 8 Nov 2013 12:41:14 +0000 (13:41 +0100)
committerWouter Wolters <typo3@wouterwolters.nl>
Thu, 12 Jun 2014 10:42:50 +0000 (12:42 +0200)
Uri parameters are overwritten when using both POST and GET parameters
with the addQueryStringMethod functionality of uri generation.

The problem is solved by using the method
GeneralUtility::array_merge_recursive_overrule() instead of array_merge
when merging the POST and GET parameters.

Resolves: #53450
Releases: 6.2
Change-Id: I39926ebbaa08f6810e440bad1f238aeb2af17e5b
Reviewed-on: https://review.typo3.org/25211
Reviewed-by: Xavier Perseguers
Tested-by: Xavier Perseguers
Tested-by: Wolfgang Wagner
Reviewed-by: Stefan Froemken
Tested-by: Stefan Froemken
Reviewed-by: Wouter Wolters
Tested-by: Wouter Wolters
typo3/sysext/extbase/Classes/Mvc/Web/Routing/UriBuilder.php
typo3/sysext/extbase/Tests/Unit/Mvc/Web/Routing/UriBuilderTest.php
typo3/sysext/frontend/Classes/ContentObject/ContentObjectRenderer.php
typo3/sysext/frontend/Tests/Unit/ContentObject/ContentObjectRendererTest.php

index 2550a53..768c7c2 100644 (file)
@@ -587,10 +587,10 @@ class UriBuilder {
                                                $arguments = \TYPO3\CMS\Core\Utility\GeneralUtility::_POST();
                                                break;
                                        case 'GET,POST':
-                                               $arguments = array_merge(\TYPO3\CMS\Core\Utility\GeneralUtility::_GET(), \TYPO3\CMS\Core\Utility\GeneralUtility::_POST());
+                                               $arguments = array_replace_recursive(\TYPO3\CMS\Core\Utility\GeneralUtility::_GET(), \TYPO3\CMS\Core\Utility\GeneralUtility::_POST());
                                                break;
                                        case 'POST,GET':
-                                               $arguments = array_merge(\TYPO3\CMS\Core\Utility\GeneralUtility::_POST(), \TYPO3\CMS\Core\Utility\GeneralUtility::_GET());
+                                               $arguments = array_replace_recursive(\TYPO3\CMS\Core\Utility\GeneralUtility::_POST(), \TYPO3\CMS\Core\Utility\GeneralUtility::_GET());
                                                break;
                                        default:
                                                $arguments = \TYPO3\CMS\Core\Utility\GeneralUtility::explodeUrl2Array(\TYPO3\CMS\Core\Utility\GeneralUtility::getIndpEnv('QUERY_STRING'), TRUE);
index 162ce0c..356eecf 100644 (file)
@@ -349,6 +349,80 @@ class UriBuilderTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
        /**
         * @test
         */
+       public function buildBackendUriWithQueryStringMethodPostGetMergesParameters() {
+               $_POST = array(
+                       'key1' => 'POST1',
+                       'key2' => 'POST2',
+                       'key3' => array(
+                               'key31' => 'POST31',
+                               'key32' => 'POST32',
+                               'key33' => array(
+                                       'key331' => 'POST331',
+                                       'key332' => 'POST332',
+                               )
+                       ),
+               );
+               $_GET = array(
+                       'key2' => 'GET2',
+                       'key3' => array(
+                               'key32' => 'GET32',
+                               'key33' => array(
+                                       'key331' => 'GET331',
+                               )
+                       )
+               );
+               $this->uriBuilder->setAddQueryString(TRUE);
+               $this->uriBuilder->setAddQueryStringMethod('POST,GET');
+               $expectedResult = $this->rawUrlEncodeSquareBracketsInUrl('mod.php?moduleToken=dummyToken&key1=POST1&key2=GET2&key3[key31]=POST31&key3[key32]=GET32&key3[key33][key331]=GET331&key3[key33][key332]=POST332');
+               $actualResult = $this->uriBuilder->buildBackendUri();
+               $this->assertEquals($expectedResult, $actualResult);
+       }
+
+       /**
+        * @test
+        */
+       public function buildBackendUriWithQueryStringMethodGetPostMergesParameters() {
+               $_GET = array(
+                       'key1' => 'GET1',
+                       'key2' => 'GET2',
+                       'key3' => array(
+                               'key31' => 'GET31',
+                               'key32' => 'GET32',
+                               'key33' => array(
+                                       'key331' => 'GET331',
+                                       'key332' => 'GET332',
+                               )
+                       ),
+               );
+               $_POST = array(
+                       'key2' => 'POST2',
+                       'key3' => array(
+                               'key32' => 'POST32',
+                               'key33' => array(
+                                       'key331' => 'POST331',
+                               )
+                       )
+               );
+               $this->uriBuilder->setAddQueryString(TRUE);
+               $this->uriBuilder->setAddQueryStringMethod('GET,POST');
+               $expectedResult = $this->rawUrlEncodeSquareBracketsInUrl('mod.php?moduleToken=dummyToken&key1=GET1&key2=POST2&key3[key31]=GET31&key3[key32]=POST32&key3[key33][key331]=POST331&key3[key33][key332]=GET332');
+               $actualResult = $this->uriBuilder->buildBackendUri();
+               $this->assertEquals($expectedResult, $actualResult);
+       }
+
+       /**
+        * Encodes square brackets in URL.
+        *
+        * @param string $string
+        * @return string
+        */
+       private function rawUrlEncodeSquareBracketsInUrl($string) {
+               return str_replace(array('[', ']'), array('%5B', '%5D'), $string);
+       }
+
+       /**
+        * @test
+        */
        public function buildFrontendUriCreatesTypoLink() {
                /** @var \TYPO3\CMS\Extbase\Mvc\Web\Routing\UriBuilder|\PHPUnit_Framework_MockObject_MockObject|\TYPO3\CMS\Core\Tests\AccessibleObjectInterface */
                $uriBuilder = $this->getAccessibleMock('TYPO3\\CMS\\Extbase\\Mvc\\Web\\Routing\\UriBuilder', array('buildTypolinkConfiguration'));
index a7234bd..dc7ee27 100644 (file)
@@ -6424,10 +6424,12 @@ class ContentObjectRenderer {
                                $currentQueryArray = GeneralUtility::_POST();
                                break;
                        case 'GET,POST':
-                               $currentQueryArray = array_merge(GeneralUtility::_GET(), GeneralUtility::_POST());
+                               $currentQueryArray = GeneralUtility::_GET();
+                               \TYPO3\CMS\Core\Utility\ArrayUtility::mergeRecursiveWithOverrule($currentQueryArray, GeneralUtility::_POST());
                                break;
                        case 'POST,GET':
-                               $currentQueryArray = array_merge(GeneralUtility::_POST(), GeneralUtility::_GET());
+                               $currentQueryArray = GeneralUtility::_POST();
+                               \TYPO3\CMS\Core\Utility\ArrayUtility::mergeRecursiveWithOverrule($currentQueryArray, GeneralUtility::_GET());
                                break;
                        default:
                                $currentQueryArray = GeneralUtility::explodeUrl2Array(GeneralUtility::getIndpEnv('QUERY_STRING'), TRUE);
index 5284483..06c94af 100644 (file)
@@ -350,6 +350,70 @@ class ContentObjectRendererTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
        }
 
        /**
+        * @test
+        */
+       public function getQueryArgumentsWithMethodPostGetMergesParameters() {
+               $_POST = array(
+                       'key1' => 'POST1',
+                       'key2' => 'POST2',
+                       'key3' => array(
+                               'key31' => 'POST31',
+                               'key32' => 'POST32',
+                               'key33' => array(
+                                       'key331' => 'POST331',
+                                       'key332' => 'POST332',
+                               )
+                       )
+               );
+               $_GET = array(
+                       'key2' => 'GET2',
+                       'key3' => array(
+                               'key32' => 'GET32',
+                               'key33' => array(
+                                       'key331' => 'GET331',
+                               )
+                       )
+               );
+               $getQueryArgumentsConfiguration = array();
+               $getQueryArgumentsConfiguration['method'] = 'POST,GET';
+               $expectedResult = $this->rawUrlEncodeSquareBracketsInUrl('&key1=POST1&key2=GET2&key3[key31]=POST31&key3[key32]=GET32&key3[key33][key331]=GET331&key3[key33][key332]=POST332');
+               $actualResult = $this->cObj->getQueryArguments($getQueryArgumentsConfiguration);
+               $this->assertEquals($expectedResult, $actualResult);
+       }
+
+       /**
+        * @test
+        */
+       public function getQueryArgumentsWithMethodGetPostMergesParameters() {
+               $_GET = array(
+                       'key1' => 'GET1',
+                       'key2' => 'GET2',
+                       'key3' => array(
+                               'key31' => 'GET31',
+                               'key32' => 'GET32',
+                               'key33' => array(
+                                       'key331' => 'GET331',
+                                       'key332' => 'GET332',
+                               )
+                       )
+               );
+               $_POST = array(
+                       'key2' => 'POST2',
+                       'key3' => array(
+                               'key32' => 'POST32',
+                               'key33' => array(
+                                       'key331' => 'POST331',
+                               )
+                       )
+               );
+               $getQueryArgumentsConfiguration = array();
+               $getQueryArgumentsConfiguration['method'] = 'GET,POST';
+               $expectedResult = $this->rawUrlEncodeSquareBracketsInUrl('&key1=GET1&key2=POST2&key3[key31]=GET31&key3[key32]=POST32&key3[key33][key331]=POST331&key3[key33][key332]=GET332');
+               $actualResult = $this->cObj->getQueryArguments($getQueryArgumentsConfiguration);
+               $this->assertEquals($expectedResult, $actualResult);
+       }
+
+       /**
         * Encodes square brackets in URL.
         *
         * @param string $string