From 75951ae8496d29970c986433f08468f019487dce Mon Sep 17 00:00:00 2001
From: Oliver Bartsch <bo@cedev.de>
Date: Fri, 28 Apr 2023 16:46:23 +0200
Subject: [PATCH] [BUGFIX] Avoid TypeError in extbase persistence

Properly check for the given value being an object before
passing it to corresponding method, which is type-hinted
since #100068.

Resolves: #100774
Related: #100068
Releases: main, 11.5
Change-Id: I704ef93ebbbfd1f161bf56dd7ef0058bd2b4875d
Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/78918
Tested-by: Oliver Bartsch <bo@cedev.de>
Reviewed-by: Oliver Bartsch <bo@cedev.de>
Tested-by: core-ci <typo3@b13.com>
---
 Build/phpstan/phpstan-baseline.neon               | 10 ++++++++++
 .../Classes/Persistence/Generic/Backend.php       |  6 ++----
 .../Unit/Persistence/Generic/BackendTest.php      | 15 +++++++++++++++
 3 files changed, 27 insertions(+), 4 deletions(-)

diff --git a/Build/phpstan/phpstan-baseline.neon b/Build/phpstan/phpstan-baseline.neon
index 04e059500844..dcfc8f96219c 100644
--- a/Build/phpstan/phpstan-baseline.neon
+++ b/Build/phpstan/phpstan-baseline.neon
@@ -2515,6 +2515,11 @@ parameters:
 			count: 1
 			path: ../../typo3/sysext/extbase/Classes/Persistence/Generic/Backend.php
 
+		-
+			message: "#^Else branch is unreachable because ternary operator condition is always true\\.$#"
+			count: 1
+			path: ../../typo3/sysext/extbase/Classes/Persistence/Generic/Backend.php
+
 		-
 			message: "#^Method TYPO3\\\\CMS\\\\Extbase\\\\Persistence\\\\ObjectMonitoringInterface\\:\\:_isDirty\\(\\) invoked with 1 parameter, 0 required\\.$#"
 			count: 1
@@ -3000,6 +3005,11 @@ parameters:
 			count: 1
 			path: ../../typo3/sysext/extbase/Tests/Unit/Object/Container/Fixtures/testclasses/t3lib_object_tests_cyclic2.php
 
+		-
+			message: "#^Parameter \\#1 \\$object of method TYPO3\\\\CMS\\\\Extbase\\\\Persistence\\\\Generic\\\\Backend\\:\\:getIdentifierByObject\\(\\) expects object, string given\\.$#"
+			count: 1
+			path: ../../typo3/sysext/extbase/Tests/Unit/Persistence/Generic/BackendTest.php
+
 		-
 			message: "#^Call to static method PHPUnit\\\\Framework\\\\Assert\\:\\:assertNull\\(\\) with object will always evaluate to false\\.$#"
 			count: 1
diff --git a/typo3/sysext/extbase/Classes/Persistence/Generic/Backend.php b/typo3/sysext/extbase/Classes/Persistence/Generic/Backend.php
index 079f7472e766..d6a44fa95384 100644
--- a/typo3/sysext/extbase/Classes/Persistence/Generic/Backend.php
+++ b/typo3/sysext/extbase/Classes/Persistence/Generic/Backend.php
@@ -192,11 +192,9 @@ class Backend implements BackendInterface, SingletonInterface
     {
         if ($object instanceof LazyLoadingProxy) {
             $object = $object->_loadRealInstance();
-            if (!is_object($object)) {
-                return null;
-            }
         }
-        return $this->session->getIdentifierByObject($object);
+
+        return is_object($object) ? $this->session->getIdentifierByObject($object) : null;
     }
 
     /**
diff --git a/typo3/sysext/extbase/Tests/Unit/Persistence/Generic/BackendTest.php b/typo3/sysext/extbase/Tests/Unit/Persistence/Generic/BackendTest.php
index 5a0aafbbfc42..f95436cbbb54 100644
--- a/typo3/sysext/extbase/Tests/Unit/Persistence/Generic/BackendTest.php
+++ b/typo3/sysext/extbase/Tests/Unit/Persistence/Generic/BackendTest.php
@@ -27,6 +27,7 @@ use TYPO3\CMS\Extbase\Persistence\Generic\LazyLoadingProxy;
 use TYPO3\CMS\Extbase\Persistence\Generic\Mapper\ColumnMap;
 use TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMap;
 use TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapFactory;
+use TYPO3\CMS\Extbase\Persistence\Generic\Session;
 use TYPO3\CMS\Extbase\Persistence\Generic\Storage\BackendInterface;
 use TYPO3\TestingFramework\Core\Unit\UnitTestCase;
 
@@ -94,6 +95,20 @@ class BackendTest extends UnitTestCase
         $fixture->_call('insertRelationInRelationtable', $domainObject, $domainObject, '');
     }
 
+    /**
+     * @test
+     */
+    public function getIdentifierByObjectWithStringInsteadOfObjectReturnsNull(): void
+    {
+        $session = $this->createMock(Session::class);
+        $session->expects(self::never())->method('getIdentifierByObject');
+
+        $backend = $this->getAccessibleMock(Backend::class, null, [$this->createMock(ConfigurationManagerInterface::class)], '', false);
+        $backend->_set('session', $session);
+
+        self::assertNull($backend->getIdentifierByObject('invalidObject'));
+    }
+
     /**
      * @test
      */
-- 
GitLab