From fbd25fd7ecff3a7113abbbfebf4466f09effd920 Mon Sep 17 00:00:00 2001
From: Oliver Bartsch <bo@cedev.de>
Date: Thu, 4 Jan 2024 14:29:41 +0100
Subject: [PATCH] [BUGFIX] Prevent InvalidArgumentException in user constraints
 calculation

An additional check is applied to prevent
an InvalidArgumentException for cases where
`checkPid_value` contains an empty string.

Resolves: #102751
Releases: main, 12.4
Change-Id: I906837e75ab505af1e46f55eeccd068c24005e98
Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/82372
Tested-by: core-ci <typo3@b13.com>
Reviewed-by: Oliver Bartsch <bo@cedev.de>
Tested-by: Oliver Bartsch <bo@cedev.de>
---
 .../AbstractUserAuthentication.php            |  2 +-
 .../AbstractUserAuthenticationTest.php        | 33 ++++++++++++++++---
 2 files changed, 30 insertions(+), 5 deletions(-)

diff --git a/typo3/sysext/core/Classes/Authentication/AbstractUserAuthentication.php b/typo3/sysext/core/Classes/Authentication/AbstractUserAuthentication.php
index 054606d5dd90..9e3b098a7edd 100644
--- a/typo3/sysext/core/Classes/Authentication/AbstractUserAuthentication.php
+++ b/typo3/sysext/core/Classes/Authentication/AbstractUserAuthentication.php
@@ -989,7 +989,7 @@ abstract class AbstractUserAuthentication implements LoggerAwareInterface
             $restrictionContainer->add(GeneralUtility::makeInstance(RootLevelRestriction::class, [$this->user_table]));
         }
 
-        if ($this->checkPid && $this->checkPid_value !== null) {
+        if ($this->checkPid && $this->checkPid_value !== null && $this->checkPid_value !== '') {
             $restrictionContainer->add(
                 GeneralUtility::makeInstance(
                     PageIdListRestriction::class,
diff --git a/typo3/sysext/core/Tests/Functional/Authentication/AbstractUserAuthenticationTest.php b/typo3/sysext/core/Tests/Functional/Authentication/AbstractUserAuthenticationTest.php
index 0cdfc28e19ca..6cf63da49139 100644
--- a/typo3/sysext/core/Tests/Functional/Authentication/AbstractUserAuthenticationTest.php
+++ b/typo3/sysext/core/Tests/Functional/Authentication/AbstractUserAuthenticationTest.php
@@ -17,10 +17,12 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\Authentication;
 
+use TYPO3\CMS\Core\Database\ConnectionPool;
 use TYPO3\CMS\Core\Database\Query\Expression\CompositeExpression;
 use TYPO3\CMS\Core\Http\ServerRequest;
 use TYPO3\CMS\Core\Session\UserSession;
 use TYPO3\CMS\Core\Tests\Functional\Authentication\Fixtures\AnyUserAuthentication;
+use TYPO3\CMS\Core\Utility\GeneralUtility;
 use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
 
 final class AbstractUserAuthenticationTest extends FunctionalTestCase
@@ -73,18 +75,41 @@ final class AbstractUserAuthenticationTest extends FunctionalTestCase
         self::assertTrue($this->subject->getModuleData(self::class));
     }
 
+    public static function getAuthInfoArrayReturnsEmptyPidListIfNoCheckPidValueIsGivenDataProvider(): array
+    {
+        return [
+            ['', ''],
+            [null, ''],
+            [0, '0'],
+            ['0', '0'],
+            ['12,31', '12, 31'],
+        ];
+    }
+
     /**
      * @test
+     * @dataProvider getAuthInfoArrayReturnsEmptyPidListIfNoCheckPidValueIsGivenDataProvider
      */
-    public function getAuthInfoArrayReturnsEmptyPidListIfNoCheckPidValueIsGiven(): void
-    {
+    public function getAuthInfoArrayReturnsCorrectPidConstraintForGivenCheckPidValue(
+        int|null|string $checkPid_value,
+        string $expectedPids
+    ): void {
         $this->subject->user_table = 'be_users';
-        $this->subject->checkPid_value = null;
+        $this->subject->checkPid_value = $checkPid_value;
 
         $authInfoArray = $this->subject->getAuthInfoArray(new ServerRequest('https://example.com'));
 
         $enableClause = $authInfoArray['db_user']['enable_clause'];
         self::assertInstanceOf(CompositeExpression::class, $enableClause);
-        self::assertSame('', (string)$enableClause);
+
+        $connection = GeneralUtility::makeInstance(ConnectionPool::class)->getConnectionForTable('be_users');
+
+        $expectedEnableClause = '';
+
+        if ($expectedPids !== '') {
+            $expectedEnableClause = $connection->quoteIdentifier('be_users.pid') . ' IN (' . $expectedPids . ')';
+        }
+
+        self::assertSame($expectedEnableClause, (string)$enableClause);
     }
 }
-- 
GitLab