[TASK] Install Tool: Validate database name against MySQL restrictions 16/43016/4
authorMorton Jonuschat <m.jonuschat@mojocode.de>
Fri, 4 Sep 2015 10:27:00 +0000 (12:27 +0200)
committerXavier Perseguers <xavier@typo3.org>
Sat, 5 Sep 2015 14:17:46 +0000 (16:17 +0200)
MySQL only allows a limited set of characters in unquoted database
names. As the database name can't be quoted for compatibility with DBAL,
the name gets validated against the given restrictions.

Resolves: #51093
Releases: master
Change-Id: I42a0fbf0c6f724245090ad503c8198372f7359d3
Reviewed-on: http://review.typo3.org/43016
Reviewed-by: Wouter Wolters <typo3@wouterwolters.nl>
Tested-by: Wouter Wolters <typo3@wouterwolters.nl>
Reviewed-by: Xavier Perseguers <xavier@typo3.org>
Tested-by: Xavier Perseguers <xavier@typo3.org>
typo3/sysext/install/Classes/Controller/Action/Step/DatabaseSelect.php

index 0b01948..04bcf92 100644 (file)
@@ -41,7 +41,7 @@ class DatabaseSelect extends AbstractStepAction {
                $configurationManager = $this->objectManager->get(\TYPO3\CMS\Core\Configuration\ConfigurationManager::class);
                if ($postValues['type'] === 'new') {
                        $newDatabaseName = $postValues['new'];
-                       if (strlen($newDatabaseName) <= 50) {
+                       if ($this->isValidDatabaseName($newDatabaseName)) {
                                $createDatabaseResult = $this->databaseConnection->admin_query('CREATE DATABASE ' . $newDatabaseName . ' CHARACTER SET utf8');
                                if ($createDatabaseResult) {
                                        $localConfigurationPathValuePairs['DB/database'] = $newDatabaseName;
@@ -51,8 +51,8 @@ class DatabaseSelect extends AbstractStepAction {
                                        $errorStatus->setTitle('Unable to create database');
                                        $errorStatus->setMessage(
                                                'Database with name ' . $newDatabaseName . ' could not be created.' .
-                                               ' Either your database name contains special chars (only alphanumeric characters are allowed)' .
-                                               ' or your database user probably does not have sufficient permissions to create it.' .
+                                               ' Either your database name contains a reserved keyword or your database' .
+                                               ' user does not have sufficient permissions to create it.' .
                                                ' Please choose an existing (empty) database or contact administration.'
                                        );
                                        $result[] = $errorStatus;
@@ -61,7 +61,11 @@ class DatabaseSelect extends AbstractStepAction {
                                /** @var $errorStatus \TYPO3\CMS\Install\Status\ErrorStatus */
                                $errorStatus = $this->objectManager->get(\TYPO3\CMS\Install\Status\ErrorStatus::class);
                                $errorStatus->setTitle('Database name not valid');
-                               $errorStatus->setMessage('Given database name must be shorter than fifty characters.');
+                               $errorStatus->setMessage(
+                                       'Given database name must be shorter than fifty characters' .
+                                       ' and consist solely of basic latin letters (a-z), digits (0-9), dollar signs ($)' .
+                                       ' and underscores (_).'
+                               );
                                $result[] = $errorStatus;
                        }
                } elseif ($postValues['type'] === 'existing' && !empty($postValues['existing'])) {
@@ -172,4 +176,14 @@ class DatabaseSelect extends AbstractStepAction {
                $this->databaseConnection->sql_pconnect();
        }
 
+       /**
+        * Validate the database name against the lowest common denominator of valid identifiers across different DBMS
+        *
+        * @param string $databaseName
+        * @return bool
+        */
+       protected function isValidDatabaseName($databaseName) {
+               return strlen($databaseName) <= 50 && preg_match('/^[a-zA-Z0-9\$_]*$/', $databaseName);
+       }
+
 }