[BUGFIX] Prevent enforcing opened database connection with initCommands 58/55558/5
authorNicole Cordes <typo3@cordes.co>
Sun, 4 Feb 2018 11:20:05 +0000 (12:20 +0100)
committerNicole Cordes <typo3@cordes.co>
Tue, 6 Feb 2018 10:01:44 +0000 (11:01 +0100)
This patch moves the execution of configured initCommands to the end
of connect function. This prevents a database connection from being
opened by default due to the execution of commands right after class
initialization and still ensures a connection is configured properly
before first command execution.

Furthermore this patch adds a new functional test for the ErrorHandler.
The test uses some predefined initCommands to enforce UTF8 support to be
set. This isn't necessary but uses initCommands in a safe way. Due to
the predefined initCommands the test failed before as the connection was
forced to be opened. For further information see the referenced forge
ticket.

Resolves: #83770
Releases: master, 8.7
Change-Id: I2287600959b3ec06d338e26373562850307ce0b1
Reviewed-on: https://review.typo3.org/55558
Tested-by: TYPO3com <no-reply@typo3.com>
Reviewed-by: Nicole Cordes <typo3@cordes.co>
Tested-by: Nicole Cordes <typo3@cordes.co>
typo3/sysext/core/Classes/Database/Connection.php
typo3/sysext/core/Tests/Functional/Error/ErrorHandlerTest.php [new file with mode: 0644]

index d7562b5..f6d99a4 100644 (file)
@@ -64,6 +64,11 @@ class Connection extends \Doctrine\DBAL\Connection
     const PARAM_BOOL = \PDO::PARAM_BOOL; // 5
 
     /**
+     * @var array
+     */
+    private $prepareConnectionCommands = [];
+
+    /**
      * Prevents the duplicate registration of event handlers and types for this connection.
      * If true the events will not be initialized any more in the connect() method.
      *
@@ -148,6 +153,16 @@ class Connection extends \Doctrine\DBAL\Connection
 
         $this->customTypesAndEventsInitialized = true;
 
+        foreach ($this->prepareConnectionCommands as $command) {
+            if ($this->executeUpdate($command) === false) {
+                GeneralUtility::sysLog(
+                    'Could not initialize DB connection with query "' . $command . '": ' . $this->errorInfo(),
+                    'core',
+                    GeneralUtility::SYSLOG_SEVERITY_ERROR
+                );
+            }
+        }
+
         return true;
     }
 
@@ -464,7 +479,7 @@ class Connection extends \Doctrine\DBAL\Connection
             return;
         }
 
-        $commandsToPerform = GeneralUtility::trimExplode(
+        $this->prepareConnectionCommands = GeneralUtility::trimExplode(
             LF,
             str_replace(
                 '\' . LF . \'',
@@ -473,16 +488,6 @@ class Connection extends \Doctrine\DBAL\Connection
             ),
             true
         );
-
-        foreach ($commandsToPerform as $command) {
-            if ($this->executeUpdate($command) === false) {
-                GeneralUtility::sysLog(
-                    'Could not initialize DB connection with query "' . $command . '": ' . $this->errorInfo(),
-                    'core',
-                    GeneralUtility::SYSLOG_SEVERITY_ERROR
-                );
-            }
-        }
     }
 
     /**
diff --git a/typo3/sysext/core/Tests/Functional/Error/ErrorHandlerTest.php b/typo3/sysext/core/Tests/Functional/Error/ErrorHandlerTest.php
new file mode 100644 (file)
index 0000000..0d34d91
--- /dev/null
@@ -0,0 +1,54 @@
+<?php
+declare(strict_types = 1);
+namespace TYPO3\CMS\Core\Tests\Functional\Error;
+
+/*
+ * 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!
+ */
+
+/**
+ * Testcase for class \TYPO3\CMS\Core\Error\ErrorHandler
+ */
+class ErrorHandlerTest extends \TYPO3\TestingFramework\Core\Functional\FunctionalTestCase
+{
+    /**
+     * @var array
+     */
+    protected $configurationToUseInTestInstance = [
+        'DB' => [
+            'Connections' => [
+                'Default' => [
+                    'initCommands' => 'SET NAMES \'UTF8\';',
+                ],
+            ],
+        ],
+        'SYS' => [
+            'exceptionalErrors' => E_ALL & ~(E_STRICT | E_NOTICE | E_COMPILE_WARNING | E_COMPILE_ERROR | E_CORE_WARNING | E_CORE_ERROR | E_PARSE | E_ERROR | E_DEPRECATED | E_USER_DEPRECATED | E_WARNING | E_USER_ERROR | E_USER_NOTICE | E_USER_WARNING),
+        ],
+    ];
+
+    /**
+     * @test
+     */
+    public function handleErrorFetchesDeprecations()
+    {
+        trigger_error(
+            'The first error triggers database connection to be initialized and should be caught.',
+            E_USER_DEPRECATED
+        );
+        trigger_error(
+            'The second error should be caught by ErrorHandler as well.',
+            E_USER_DEPRECATED
+        );
+        $this->assertTrue(true);
+    }
+}