From 92496f92a2f8504f421d6b2777e4dbe4bc0b8d7b Mon Sep 17 00:00:00 2001
From: Markus Klein <markus.klein@typo3.org>
Date: Tue, 31 Oct 2017 07:51:35 +0100
Subject: [PATCH] [BUGFIX] Add checks to ReflectionService to have correct
 return values

Resolves: #82885
Releases: master, 8.7
Change-Id: I422f920187186fe83b6043f806fc1be9a16c8a25
Reviewed-on: https://review.typo3.org/54510
Tested-by: TYPO3com <no-reply@typo3.com>
Reviewed-by: Alexander Schnitzler <review.typo3.org@alexanderschnitzler.de>
Tested-by: Alexander Schnitzler <review.typo3.org@alexanderschnitzler.de>
Reviewed-by: Susanne Moog <susanne.moog@typo3.org>
Tested-by: Susanne Moog <susanne.moog@typo3.org>
---
 .../Classes/Reflection/ReflectionService.php  | 31 +++++++++----------
 .../Unit/Reflection/ReflectionServiceTest.php | 15 +++++++++
 2 files changed, 30 insertions(+), 16 deletions(-)

diff --git a/typo3/sysext/extbase/Classes/Reflection/ReflectionService.php b/typo3/sysext/extbase/Classes/Reflection/ReflectionService.php
index 400a3c9978d7..b6ecbfdb99cb 100644
--- a/typo3/sysext/extbase/Classes/Reflection/ReflectionService.php
+++ b/typo3/sysext/extbase/Classes/Reflection/ReflectionService.php
@@ -61,14 +61,14 @@ class ReflectionService implements SingletonInterface
      *
      * @param CacheManager $cacheManager
      */
-    public function __construct(\TYPO3\CMS\Core\Cache\CacheManager $cacheManager = null)
+    public function __construct(CacheManager $cacheManager = null)
     {
         if ($cacheManager instanceof CacheManager && $cacheManager->hasCache(static::CACHE_IDENTIFIER)) {
             $this->cachingEnabled = true;
             $this->dataCache = $cacheManager->getCache(static::CACHE_IDENTIFIER);
 
-            if (($classSchemata = $this->dataCache->has(static::CACHE_ENTRY_IDENTIFIER)) !== false) {
-                $this->classSchemata = $this->dataCache->get(static::CACHE_ENTRY_IDENTIFIER);
+            if (($classSchemata = $this->dataCache->get(static::CACHE_ENTRY_IDENTIFIER)) !== false) {
+                $this->classSchemata = $classSchemata;
             }
         }
     }
@@ -112,7 +112,7 @@ class ReflectionService implements SingletonInterface
             return [];
         }
 
-        return $classSchema->getTags()[$tag];
+        return $classSchema->getTags()[$tag] ?? [];
     }
 
     /**
@@ -183,7 +183,7 @@ class ReflectionService implements SingletonInterface
             return [];
         }
 
-        return $classSchema->getMethod($methodName)['tags'];
+        return $classSchema->getMethod($methodName)['tags'] ?? [];
     }
 
     /**
@@ -202,7 +202,7 @@ class ReflectionService implements SingletonInterface
             return [];
         }
 
-        return $classSchema->getMethod($methodName)['params'];
+        return $classSchema->getMethod($methodName)['params'] ?? [];
     }
 
     /**
@@ -220,9 +220,7 @@ class ReflectionService implements SingletonInterface
             return [];
         }
 
-        $propertyDefinition = $classSchema->getProperty($propertyName);
-
-        return isset($propertyDefinition['tags']) ? $propertyDefinition['tags'] : [];
+        return $classSchema->getProperty($propertyName)['tags'] ?? [];
     }
 
     /**
@@ -235,11 +233,13 @@ class ReflectionService implements SingletonInterface
      */
     public function getPropertyTagValues($className, $propertyName, $tag): array
     {
-        if (!$this->isPropertyTaggedWith($className, $propertyName, $tag)) {
+        try {
+            $classSchema = $this->getClassSchema($className);
+        } catch (\Exception $e) {
             return [];
         }
 
-        return $this->getClassSchema($className)->getProperty($propertyName)['tags'][$tag];
+        return $classSchema->getProperty($propertyName)['tags'][$tag] ?? [];
     }
 
     /**
@@ -297,15 +297,14 @@ class ReflectionService implements SingletonInterface
      * @param string $className
      * @throws Exception\UnknownClassException
      * @return ClassSchema The class schema
-     * @throws \ReflectionException
      */
     protected function buildClassSchema($className): ClassSchema
     {
-        if (!class_exists($className)) {
-            throw new Exception\UnknownClassException('The classname "' . $className . '" was not found and thus can not be reflected.', 1278450972);
+        try {
+            $classSchema = new ClassSchema($className);
+        } catch (\ReflectionException $e) {
+            throw new Exception\UnknownClassException('The classname "' . $className . '" was not found and thus can not be reflected.', 1278450972, $e);
         }
-
-        $classSchema = new ClassSchema($className);
         $this->classSchemata[$className] = $classSchema;
         $this->dataCacheNeedsUpdate = true;
         return $classSchema;
diff --git a/typo3/sysext/extbase/Tests/Unit/Reflection/ReflectionServiceTest.php b/typo3/sysext/extbase/Tests/Unit/Reflection/ReflectionServiceTest.php
index 538ef662fe1e..680741acc6c8 100644
--- a/typo3/sysext/extbase/Tests/Unit/Reflection/ReflectionServiceTest.php
+++ b/typo3/sysext/extbase/Tests/Unit/Reflection/ReflectionServiceTest.php
@@ -70,6 +70,11 @@ class ReflectionServiceTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCa
             'test for reflection',
         ], $classValues);
 
+        $this->assertEquals(
+            [],
+            $service->getClassTagValues(static::class, 'nonExistantTag')
+        );
+
         $this->assertEquals(
             [],
             $service->getClassTagValues('NonExistantNamespace\\NonExistantClass', 'nonExistantTag')
@@ -99,6 +104,11 @@ class ReflectionServiceTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCa
             'return' => ['string']
         ], $tagsValues);
 
+        $this->assertEquals(
+            [],
+            $service->getMethodTagsValues(static::class, 'notExistentMethod')
+        );
+
         $this->assertEquals(
             [],
             $service->getMethodTagsValues('NonExistantNamespace\\NonExistantClass', 'notExistentMethod')
@@ -129,6 +139,11 @@ class ReflectionServiceTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCa
             ]
         ], $parameters);
 
+        $this->assertSame(
+            [],
+            $service->getMethodParameters(static::class, 'notExistentMethod')
+        );
+
         $this->assertSame(
             [],
             $service->getMethodParameters('NonExistantNamespace\\NonExistantClass', 'notExistentMethod')
-- 
GitLab