From 7adc8e074b4fc51483c5f922a0ef9e924ed88261 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Christian=20E=C3=9Fl?= <indy.essl@gmail.com>
Date: Fri, 27 Mar 2020 13:24:36 +0100
Subject: [PATCH] [BUGFIX] Allow multiline comments in SqlReader

When using c-style multiline comments in the ext_tables.sql of an
extension, the SchemaMigrator would then ignore the subsequent
"CREATE TABLE" statement, because the SqlReader also read the multiline
comments into the statement array.
This patch fixes this behaviour.
Now the following comments are possible inside ext_tables.sql:

/*
 Some comment text
 more text
*/

/* Same line c-style comment */

/* More multiline
 comments */

CREATE TABLE table1 (
    header varchar(255) DEFAULT '' NOT NULL,
    bodytext text
);

Resolves: #89714
Releases: master, 9.5
Change-Id: I49e687215d0b42d6ca5416c687fdbc19b44d237d
Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/63951
Tested-by: TYPO3com <noreply@typo3.com>
Tested-by: Susanne Moog <look@susi.dev>
Tested-by: Daniel Goerz <daniel.goerz@posteo.de>
Reviewed-by: Susanne Moog <look@susi.dev>
Reviewed-by: Daniel Goerz <daniel.goerz@posteo.de>
---
 .../Classes/Database/Schema/SqlReader.php     | 12 +++++-
 .../Unit/Database/Schema/SqlReaderTest.php    | 38 +++++++++++++++++++
 2 files changed, 49 insertions(+), 1 deletion(-)

diff --git a/typo3/sysext/core/Classes/Database/Schema/SqlReader.php b/typo3/sysext/core/Classes/Database/Schema/SqlReader.php
index 120f962feb88..0a2ffc1f3b3f 100644
--- a/typo3/sysext/core/Classes/Database/Schema/SqlReader.php
+++ b/typo3/sysext/core/Classes/Database/Schema/SqlReader.php
@@ -89,11 +89,21 @@ class SqlReader
     {
         $statementArray = [];
         $statementArrayPointer = 0;
+        $isInMultilineComment = false;
         foreach (explode(LF, $dumpContent) as $lineContent) {
             $lineContent = trim($lineContent);
 
             // Skip empty lines and comments
-            if ($lineContent === '' || $lineContent[0] === '#' || strpos($lineContent, '--') === 0) {
+            if ($lineContent === '' || $lineContent[0] === '#' || strpos($lineContent, '--') === 0 ||
+                strpos($lineContent, '/*') === 0 || substr($lineContent, -2) === '*/' || $isInMultilineComment
+            ) {
+                // skip c style multiline comments
+                if (strpos($lineContent, '/*') === 0 && substr($lineContent, -2) !== '*/') {
+                    $isInMultilineComment = true;
+                }
+                if (substr($lineContent, -2) === '*/') {
+                    $isInMultilineComment = false;
+                }
                 continue;
             }
 
diff --git a/typo3/sysext/core/Tests/Unit/Database/Schema/SqlReaderTest.php b/typo3/sysext/core/Tests/Unit/Database/Schema/SqlReaderTest.php
index 9c64f6f08f02..c40d7674baa0 100644
--- a/typo3/sysext/core/Tests/Unit/Database/Schema/SqlReaderTest.php
+++ b/typo3/sysext/core/Tests/Unit/Database/Schema/SqlReaderTest.php
@@ -111,4 +111,42 @@ class SqlReaderTest extends UnitTestCase
         self::assertCount(1, $result);
         self::assertStringStartsWith('CREATE TABLE', array_pop($result));
     }
+
+    /**
+     * @param string $comment
+     * @dataProvider commentProvider
+     * @test
+     */
+    public function getCreateTableStatementArrayResultWithComment(string $comment)
+    {
+        $subject = new SqlReader($this->prophesize(EventDispatcherInterface::class)->reveal(), $this->prophesize(PackageManager::class)->reveal());
+        $result = $subject->getCreateTableStatementArray(
+            $comment . LF . 'CREATE TABLE aTestTable(' . LF . '  aTestField INT(11)' . LF . ');' .
+            LF .
+            'INSERT INTO aTestTable(`aTestField`) VALUES(1);'
+        );
+        self::assertCount(1, $result);
+        self::assertStringStartsWith('CREATE TABLE', array_pop($result));
+    }
+
+    public function commentProvider(): array
+    {
+        return [
+            'Single line comment starting with "#"' => [
+                '# Comment'
+            ],
+            'Single line comment starting with "--"' => [
+                '-- Comment'
+            ],
+            'Single line c-style comment' => [
+                '/* Same line c-style comment */'
+            ],
+            'Multiline comment variant 1' => [
+                '/*' . LF . 'Some comment text' . LF . 'more text' . LF . '*/'
+            ],
+            'Multiline comment variant 2' => [
+                '/* More' . LF . ' comments */'
+            ]
+        ];
+    }
 }
-- 
GitLab