[BUGFIX] Handle missing TSFE gracefully in TS conditions 29/59129/7
authorGeorg Ringer <georg.ringer@gmail.com>
Wed, 12 Dec 2018 22:58:39 +0000 (23:58 +0100)
committerDaniel Goerz <daniel.goerz@posteo.de>
Sun, 12 Jan 2020 17:16:45 +0000 (18:16 +0100)
A condition like [getTSFE().id == 1] is evaluated in BE as well
and logged an error 'Unable to get a property on a non-object'.

This patch ensures that conditions based on getTSFE() are
treated gracefully and are evaluated to false.

Resolves: #87021
Releases: master, 9.5
Change-Id: If56a8b7bd66b9f7e66bdc8ce5f56c8df890cf655
Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/59129
Tested-by: TYPO3com <noreply@typo3.com>
Tested-by: Markus Klein <markus.klein@typo3.org>
Tested-by: Susanne Moog <look@susi.dev>
Tested-by: Daniel Goerz <daniel.goerz@posteo.de>
Reviewed-by: Markus Klein <markus.klein@typo3.org>
Reviewed-by: Susanne Moog <look@susi.dev>
Reviewed-by: Daniel Goerz <daniel.goerz@posteo.de>
typo3/sysext/backend/Tests/Functional/Configuration/TypoScript/ConditionMatching/ConditionMatcherTest.php
typo3/sysext/core/Classes/Configuration/TypoScript/ConditionMatching/AbstractConditionMatcher.php
typo3/sysext/core/Classes/Exception/MissingTsfeException.php [new file with mode: 0644]
typo3/sysext/core/Classes/ExpressionLanguage/FunctionsProvider/Typo3ConditionFunctionsProvider.php
typo3/sysext/core/Documentation/Changelog/9.4/Feature-85829-ImplementSymfonyExpressionLanguageForTypoScriptConditions.rst

index 6855916..88cccdf 100644 (file)
@@ -272,4 +272,12 @@ class ConditionMatcherTest extends FunctionalTestCase
         putenv($testKey . '=testValue');
         self::assertTrue($this->subject->match('[getenv("' . $testKey . '") == "testValue"]'));
     }
+
+    /**
+     * @test
+     */
+    public function usingTSFEInATestInBeContextIsAlwaysFalse(): void
+    {
+        self::assertFalse($this->subject->match('[getTSFE().id == 1]'));
+    }
 }
index d8a239f..f7b08a2 100644 (file)
@@ -19,6 +19,7 @@ use Psr\Log\LoggerAwareTrait;
 use Symfony\Component\ExpressionLanguage\SyntaxError;
 use TYPO3\CMS\Core\Configuration\TypoScript\Exception\InvalidTypoScriptConditionException;
 use TYPO3\CMS\Core\Error\Exception;
+use TYPO3\CMS\Core\Exception\MissingTsfeException;
 use TYPO3\CMS\Core\ExpressionLanguage\Resolver;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
 
@@ -192,6 +193,10 @@ abstract class AbstractConditionMatcher implements LoggerAwareInterface, Conditi
             if ($result !== null) {
                 return $result;
             }
+        } catch (MissingTsfeException $e) {
+            // TSFE is not available in the current context (e.g. TSFE in BE context),
+            // we set all conditions false for this case.
+            return false;
         } catch (SyntaxError $exception) {
             $message = 'Expression could not be parsed.';
             $this->logger->error($message, ['expression' => $expression]);
diff --git a/typo3/sysext/core/Classes/Exception/MissingTsfeException.php b/typo3/sysext/core/Classes/Exception/MissingTsfeException.php
new file mode 100644 (file)
index 0000000..ea9d4b6
--- /dev/null
@@ -0,0 +1,21 @@
+<?php
+declare(strict_types = 1);
+
+namespace TYPO3\CMS\Core\Exception;
+
+/*
+ * 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!
+ */
+
+class MissingTsfeException extends \RuntimeException
+{
+}
index 96903ea..44fcf2c 100644 (file)
@@ -17,10 +17,12 @@ namespace TYPO3\CMS\Core\ExpressionLanguage\FunctionsProvider;
 
 use Symfony\Component\ExpressionLanguage\ExpressionFunction;
 use Symfony\Component\ExpressionLanguage\ExpressionFunctionProviderInterface;
+use TYPO3\CMS\Core\Exception\MissingTsfeException;
 use TYPO3\CMS\Core\ExpressionLanguage\RequestWrapper;
 use TYPO3\CMS\Core\Site\Entity\Site;
 use TYPO3\CMS\Core\Site\Entity\SiteLanguage;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
+use TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController;
 
 /**
  * Class TypoScriptConditionProvider
@@ -65,7 +67,10 @@ class Typo3ConditionFunctionsProvider implements ExpressionFunctionProviderInter
         return new ExpressionFunction('getTSFE', function () {
             // Not implemented, we only use the evaluator
         }, function ($arguments) {
-            return $GLOBALS['TSFE'];
+            if (($GLOBALS['TSFE'] ?? null) instanceof TypoScriptFrontendController) {
+                return $GLOBALS['TSFE'];
+            }
+            throw new MissingTsfeException('TSFE is not available in this context', 1578831632);
         });
     }
 
index d3f96b7..0e8c0a8 100644 (file)
@@ -159,6 +159,9 @@ The following functions are available in **any** context:
 |                        |                       | * `[loginUser('*') == false]` // not logged in          |
 +------------------------+-----------------------+---------------------------------------------------------+
 | getTSFE                | Object                | TypoScriptFrontendController (`$GLOBALS['TSFE']`)       |
+|                        |                       |                                                         |
+|                        |                       | Conditions based on `getTSFE()` used in a context where |
+|                        |                       | TSFE is not available will always evaluate to false.    |
 +------------------------+-----------------------+---------------------------------------------------------+
 | getenv                 | String                | PHP function: :php:`getenv()`                           |
 +------------------------+-----------------------+---------------------------------------------------------+