[BUGFIX] Catch ExpressionLanguage exception for invalid base variants 01/59901/5
authorBenni Mack <benni@typo3.org>
Thu, 7 Mar 2019 18:44:16 +0000 (19:44 +0100)
committerGeorg Ringer <georg.ringer@gmail.com>
Fri, 8 Mar 2019 08:42:15 +0000 (09:42 +0100)
When adding an invalid expression for base variants,
an error is now caught instead of breaking the system.

Resolves: #87859
Releases: master, 9.5
Change-Id: I05bc10cd5f6bea7f9929c67d709cd8a0de908478
Reviewed-on: https://review.typo3.org/c/59901
Tested-by: Susanne Moog <susanne.moog@typo3.org>
Tested-by: TYPO3com <noreply@typo3.com>
Tested-by: Georg Ringer <georg.ringer@gmail.com>
Reviewed-by: Susanne Moog <susanne.moog@typo3.org>
Reviewed-by: Georg Ringer <georg.ringer@gmail.com>
typo3/sysext/core/Classes/Site/Entity/Site.php

index 6607b02..ce36a94 100644 (file)
@@ -17,6 +17,7 @@ namespace TYPO3\CMS\Core\Site\Entity;
  */
 
 use Psr\Http\Message\UriInterface;
+use Symfony\Component\ExpressionLanguage\SyntaxError;
 use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
 use TYPO3\CMS\Core\Error\PageErrorHandler\FluidPageErrorHandler;
 use TYPO3\CMS\Core\Error\PageErrorHandler\InvalidPageErrorHandlerException;
@@ -95,40 +96,20 @@ class Site implements SiteInterface
                 'direction' => '',
             ]
         ];
-        $baseUrl = $configuration['base'] ?? '';
-        if (is_array($configuration['baseVariants'] ?? false)) {
-            $expressionLanguageResolver = GeneralUtility::makeInstance(
-                Resolver::class,
-                'site',
-                []
-            );
-            foreach ($configuration['baseVariants'] as $baseVariant) {
-                if ($expressionLanguageResolver->evaluate($baseVariant['condition'])) {
-                    $baseUrl = $baseVariant['base'];
-                    break;
-                }
-            }
-        }
+        $baseUrl = $this->resolveBaseWithVariants(
+            $configuration['base'] ?? '',
+            $configuration['baseVariants'] ?? null
+        );
         $this->base = new Uri($this->sanitizeBaseUrl($baseUrl));
 
         foreach ($configuration['languages'] as $languageConfiguration) {
             $languageUid = (int)$languageConfiguration['languageId'];
             // site language has defined its own base, this is the case most of the time.
             if (!empty($languageConfiguration['base'])) {
-                $base = $languageConfiguration['base'];
-                if (is_array($languageConfiguration['baseVariants'] ?? false)) {
-                    $expressionLanguageResolver = $expressionLanguageResolver ?? GeneralUtility::makeInstance(
-                        Resolver::class,
-                        'site',
-                        []
-                    );
-                    foreach ($languageConfiguration['baseVariants'] as $baseVariant) {
-                        if ($expressionLanguageResolver->evaluate($baseVariant['condition'])) {
-                            $base = $baseVariant['base'];
-                            break;
-                        }
-                    }
-                }
+                $base = $this->resolveBaseWithVariants(
+                    $languageConfiguration['base'],
+                    $languageConfiguration['baseVariants'] ?? null
+                );
                 $base = new Uri($this->sanitizeBaseUrl($base));
                 // no host given by the language-specific base, so lets prefix the main site base
                 if ($base->getScheme() === null && $base->getHost() === '') {
@@ -162,6 +143,36 @@ class Site implements SiteInterface
     }
 
     /**
+     * Checks if the base has variants, and takes the first variant which matches an expression.
+     *
+     * @param string $baseUrl
+     * @param array|null $baseVariants
+     * @return string
+     */
+    protected function resolveBaseWithVariants(string $baseUrl, ?array $baseVariants): string
+    {
+        if (!empty($baseVariants)) {
+            $expressionLanguageResolver = GeneralUtility::makeInstance(
+                Resolver::class,
+                'site',
+                []
+            );
+            foreach ($baseVariants as $baseVariant) {
+                try {
+                    if ($expressionLanguageResolver->evaluate($baseVariant['condition'])) {
+                        $baseUrl = $baseVariant['base'];
+                        break;
+                    }
+                } catch (SyntaxError $e) {
+                    // silently fail and do not evaluate
+                    // no logger here, as Site is currently cached and serialized
+                }
+            }
+        }
+        return $baseUrl;
+    }
+
+    /**
      * Gets the identifier of this site,
      * mainly used when maintaining / configuring sites.
      *