[BUGFIX] Fix wrong usage of $callback in ArrayUtility::filterRecursive 68/56368/7
authorStephan Jorek <stephan.jorek@gmail.com>
Mon, 19 Mar 2018 16:32:54 +0000 (17:32 +0100)
committerFrank Naegler <frank.naegler@typo3.org>
Thu, 29 Mar 2018 15:32:59 +0000 (17:32 +0200)
Change closure call of callable-typed $callback in
\TYPO3\CMS\Core\Utility\ArrayUtility::filterRecursive to call_user_func().
Add test to ArrayUtilityTest to verify the correct behaviour.

Resolves: #84485
Releases: master
Change-Id: If3e2362fc7393634032f93a4f6e89e27bb5b7fc9
Reviewed-on: https://review.typo3.org/56368
Tested-by: TYPO3com <no-reply@typo3.com>
Reviewed-by: Daniel Goerz <ervaude@gmail.com>
Reviewed-by: Steffen Frese <steffenf14@gmail.com>
Reviewed-by: Alexander Opitz <opitz.alexander@googlemail.com>
Tested-by: Alexander Opitz <opitz.alexander@googlemail.com>
Reviewed-by: Christian Kuhn <lolli@schwarzbu.ch>
Tested-by: Christian Kuhn <lolli@schwarzbu.ch>
Reviewed-by: Frank Naegler <frank.naegler@typo3.org>
Tested-by: Frank Naegler <frank.naegler@typo3.org>
typo3/sysext/core/Classes/Utility/ArrayUtility.php
typo3/sysext/core/Tests/Unit/Utility/ArrayUtilityTest.php
typo3/sysext/core/Tests/Unit/Utility/Fixtures/ArrayUtilityFilterRecursiveCallbackFixture.php [new file with mode: 0644]

index 27a7d74..a7dc068 100644 (file)
@@ -856,7 +856,7 @@ class ArrayUtility
                 $array[$key] = self::filterRecursive($value, $callback);
             }
 
-            if (!$callback($value)) {
+            if (!call_user_func($callback, $value)) {
                 unset($array[$key]);
             }
         }
index d4adb32..c953e92 100644 (file)
@@ -15,6 +15,7 @@ namespace TYPO3\CMS\Core\Tests\Unit\Utility;
  * The TYPO3 project - inspiring people to share!
  */
 
+use TYPO3\CMS\Core\Tests\Unit\Utility\Fixtures\ArrayUtilityFilterRecursiveCallbackFixture;
 use TYPO3\CMS\Core\Utility\ArrayUtility;
 use TYPO3\CMS\Core\Utility\Exception\MissingArrayPathException;
 use TYPO3\TestingFramework\Core\Unit\UnitTestCase;
@@ -2880,4 +2881,65 @@ class ArrayUtilityTest extends UnitTestCase
         );
         $this->assertEquals($expectedResult, $result);
     }
+
+    /**
+     * Data provider for filterRecursiveSupportsCallableCallback
+     * @return array
+     */
+    public function filterRecursiveSupportsCallableCallbackDataProvider()
+    {
+        $input = [
+            'foo' => 'remove',
+            'bar' => [
+                'baz' => 'remove',
+                'keep1' => 'keep'
+            ],
+            'keep2' => 'keep'
+        ];
+        $expectedResult = [
+            'bar' => [
+                'keep1' => 'keep'
+            ],
+            'keep2' => 'keep'
+        ];
+
+        return [
+            'filter using a closure' => [
+                $input,
+                $expectedResult,
+                function ($value): bool {
+                    return is_array($value) || $value === 'keep';
+                },
+            ],
+            'filter using a callable "static class-method call" as string' => [
+                $input,
+                $expectedResult,
+                ArrayUtilityFilterRecursiveCallbackFixture::class . '::callbackViaStaticMethod',
+            ],
+            'filter using a callable "static class-method call" as array' => [
+                $input,
+                $expectedResult,
+                [ArrayUtilityFilterRecursiveCallbackFixture::class, 'callbackViaStaticMethod'],
+            ],
+            'filter using a callable "instance-method call" as array' => [
+                $input,
+                $expectedResult,
+                [new ArrayUtilityFilterRecursiveCallbackFixture(), 'callbackViaInstanceMethod'],
+            ],
+        ];
+    }
+
+    /**
+     * @test
+     * @dataProvider filterRecursiveSupportsCallableCallbackDataProvider
+     * @param array    $input
+     * @param array    $expectedResult
+     * @param callable $callback
+     * @see https://forge.typo3.org/issues/84485
+     */
+    public function filterRecursiveSupportsCallableCallback(array $input, array $expectedResult, callable $callback)
+    {
+        $result = ArrayUtility::filterRecursive($input, $callback);
+        $this->assertEquals($expectedResult, $result);
+    }
 }
diff --git a/typo3/sysext/core/Tests/Unit/Utility/Fixtures/ArrayUtilityFilterRecursiveCallbackFixture.php b/typo3/sysext/core/Tests/Unit/Utility/Fixtures/ArrayUtilityFilterRecursiveCallbackFixture.php
new file mode 100644 (file)
index 0000000..b487996
--- /dev/null
@@ -0,0 +1,40 @@
+<?php
+declare(strict_types = 1);
+namespace TYPO3\CMS\Core\Tests\Unit\Utility\Fixtures;
+
+/*
+ * This file is part of the TYPO3 CMS project.
+ *
+ * It is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License, either version 2
+ * of the License, or any later version.
+ *
+ * For the full copyright and license information, please read the
+ * LICENSE.txt file that was distributed with this source code.
+ *
+ * The TYPO3 project - inspiring people to share!
+ */
+
+/**
+ * Fixture for a base class
+ */
+class ArrayUtilityFilterRecursiveCallbackFixture
+{
+    /**
+     * @param mixed $value
+     * @return bool
+     */
+    public function callbackViaInstanceMethod($value): bool
+    {
+        return is_array($value) || $value === 'keep';
+    }
+
+    /**
+     * @param mixed $value
+     * @return bool
+     */
+    public static function callbackViaStaticMethod($value): bool
+    {
+        return is_array($value) || $value === 'keep';
+    }
+}