From e48ba9640f62671d0fd1600eab6cb82134cdb6c8 Mon Sep 17 00:00:00 2001
From: Christian Kuhn <lolli@schwarzbu.ch>
Date: Tue, 14 Mar 2023 16:55:01 +0100
Subject: [PATCH] [BUGFIX] TS parser: Avoid warning on invalid directories

Having an invalid wildcard import to a not existing directory
should not raise a "No such file or directory" PHP warning:

@import 'EXT:sitepackage/.../NonExistingFolder/*.tsconfig'

Resolves: #100121
Releases: main
Change-Id: Ice567b27cfd78c166e2de2e61801fc8c02cf8a72
Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/78125
Tested-by: Oliver Bartsch <bo@cedev.de>
Reviewed-by: Oliver Bartsch <bo@cedev.de>
Tested-by: core-ci <typo3@b13.com>
Reviewed-by: Oliver Klee <typo3-coding@oliverklee.de>
Tested-by: Oliver Klee <typo3-coding@oliverklee.de>
Reviewed-by: Christian Kuhn <lolli@schwarzbu.ch>
Tested-by: Christian Kuhn <lolli@schwarzbu.ch>
---
 .../IncludeTree/TreeFromLineStreamBuilder.php          |  9 +++++++--
 .../IncludeTree/TreeFromLineStreamBuilderTest.php      | 10 ++++++++++
 2 files changed, 17 insertions(+), 2 deletions(-)

diff --git a/typo3/sysext/core/Classes/TypoScript/IncludeTree/TreeFromLineStreamBuilder.php b/typo3/sysext/core/Classes/TypoScript/IncludeTree/TreeFromLineStreamBuilder.php
index 9b2f26ecd5ed..d6e9d2a05e9c 100644
--- a/typo3/sysext/core/Classes/TypoScript/IncludeTree/TreeFromLineStreamBuilder.php
+++ b/typo3/sysext/core/Classes/TypoScript/IncludeTree/TreeFromLineStreamBuilder.php
@@ -95,7 +95,7 @@ final class TreeFromLineStreamBuilder
      * a given source stream of lines exactly once, but creates a two-level
      * include node structure from it:
      *
-     * For instance, when a condition is encountered, it created a node for the
+     * For instance, when a condition is encountered, it creates a node for the
      * condition, and the "body" lines of the condition are child nodes of the
      * condition node. The $previousNode <-> $node juggling handles this: When
      * the condition body ends (new condition, or [end] or similar), the
@@ -296,11 +296,16 @@ final class TreeFromLineStreamBuilder
         } elseif (str_contains($absoluteFileName, '*')) {
             // Something with * in file part
             $directory = rtrim(dirname($absoluteFileName) . '/');
-            if (!is_dir($directory) && str_starts_with($atImportValue, './') && !$tryRelative) {
+            $directoryExists = is_dir($directory);
+            if (!$directoryExists && str_starts_with($atImportValue, './') && !$tryRelative) {
                 // See if we can import some relative wildcard like "./Setup/*" or "./Setup/*.typoscript"
                 $this->processAtImport($fileSuffix, $node, $atImportValueToken, $atImportLine, true);
                 return;
             }
+            if (!$directoryExists) {
+                // Absolute directory. There is nothing to import if the directory does not exist.
+                return;
+            }
             $filePattern = basename($absoluteFileName);
             if (!str_contains($filePattern, '*')) {
                 return;
diff --git a/typo3/sysext/core/Tests/Functional/TypoScript/IncludeTree/TreeFromLineStreamBuilderTest.php b/typo3/sysext/core/Tests/Functional/TypoScript/IncludeTree/TreeFromLineStreamBuilderTest.php
index 3cbe4725dde0..67efb1fbb2ce 100644
--- a/typo3/sysext/core/Tests/Functional/TypoScript/IncludeTree/TreeFromLineStreamBuilderTest.php
+++ b/typo3/sysext/core/Tests/Functional/TypoScript/IncludeTree/TreeFromLineStreamBuilderTest.php
@@ -465,6 +465,16 @@ class TreeFromLineStreamBuilderTest extends FunctionalTestCase
             $expectedTree,
         ];
 
+        $atImportStatement = '@import "EXT:core/Tests/Functional/TypoScript/IncludeTree/Fixtures/AtImport/NotExistingDirectory/*.typoscript"';
+        $atImportLineStream = (new LosslessTokenizer())->tokenize($atImportStatement);
+        $expectedTree = new FileInclude();
+        $expectedTree->setLineStream($atImportLineStream);
+        $expectedTree->setSplit();
+        yield 'atImport with *.typoscript on not existing directory does not crash' => [
+            $atImportLineStream,
+            $expectedTree,
+        ];
+
         $atImportStatement = '@import "EXT:core/Tests/Functional/TypoScript/IncludeTree/Fixtures/AtImport/AbsoluteImport/Scenario1/*.typoscript"';
         $atImportLineStream = (new LosslessTokenizer())->tokenize($atImportStatement);
         $atImportLine = iterator_to_array($atImportLineStream->getNextLine())[0];
-- 
GitLab