Follow-up to #203955: Create database at installation time
Expected Behavior
Illegal characters in database names (those not passing this regex: /[^A-Za-z0-9_.]+/) are handled appropriately for automatic database creation stage of the installer. "Appropriately" could mean different things—validation or normalization of the typed input.
Actual Behavior
If illegal characters are used in the database name, the user sees the "Drupal is already installed message", which is not true. Drupal is not installed and things are quite broken. Actually - the will have to recopy the settings files and start over. But Drupal doesn't explain what is happening.
Error now appears as (to screen or in logs depending on settings):
Uncaught exception 'Symfony\Component\DependencyInjection\Exception\InvalidArgumentException' with message 'The service definition "renderer" does not exist.' in core/vendor/symfony/dependency-injection/ContainerBuilder.php:868
Stack trace: #0 core/vendor/symfony/dependency-injection/ContainerBuilder.php(478): Symfony\Component\DependencyInjection\ContainerBuilder->getDefinition('renderer')
#1 core/lib/Drupal.php(157): Symfony\Component\DependencyInjection\ContainerBuilder->get('renderer')
#2 core/includes/install.core.inc(1152): Drupal::service('renderer')
#3 core/includes/install.core.inc(1090): install_database_errors(Array, './sites/default...')
#4 core/includes/install.core.inc(369): install_verify_database_settings('sites/default')
#5 core/includes/install.core.inc(113): insta in core/vendor/symfony/dependency-injection/ContainerBuilder.php on line 868Steps to Reproduce
As described in the original report #203955-68: Create database at installation time:
- Try to install Drupal with a database by the name of test-database
- A database called testdatabase will be created
- 'database' => 'test-database' will be inserted into settings.php
- Installation will fail due to Drupal not being able to connect to the database
Because database creation occurs BEFORE install_settings_form_validate we can't just inform the user that the name is invalid, rather we have to ensure that the same escaped name is placed into settings.php. As a caveat, perhaps this should only be escaped if Drupal creates the database.
We also need to ensure that the SQLite implementation is not escaped as an escaped filepath (stripped of /) causes install errors for obvious reasons. So we cannot simply run some REGEX over $database['database'] before being written to settings.php.
Rather I have a feeling we may have to call escapeDatabase so that each of the database drivers may handle the escape in the same way they do when createDatabase is called.
| Comment | File | Size | Author |
|---|---|---|---|
| #22 | interdiff.txt | 468 bytes | jeroent |
| #22 | illegal_characters_in-2525906-22.patch | 9.12 KB | jeroent |
| #14 | illegal_characters_in-2525906-14.patch | 9.12 KB | jeroent |
| #8 | illegal_characters_in-2525906-8.patch | 7.31 KB | cilefen |
| #8 | interdiff-2525906.txt | 5.16 KB | cilefen |
Comments
Comment #1
cilefen commentedSome patches were offered after comment #68 in the parent issue: #203955-68: Create database at installation time
Comment #2
cilefen commentedI am bumping this to major because it should be. Anyone in this situation will have a broken install and won't know what to do to fix it.
Comment #3
cilefen commentedComment #4
cilefen commentedCommas also cause this.
Comment #5
cilefen commentedComment #6
cilefen commentedI feel it is wrong to escape the typed database name without telling the user. So #5 throws a new exception that is caught in the database install task and is sent up to the install form.
Comment #7
larowlanThis feels wrong. Why not set the message on the Exception when it is created and then use $e->getMessage()?
Comment #8
cilefen commentedComment #9
cilefen commentedI feel that we should add an isValidDatabaseName() method to the Connection class to improve readability.
Comment #10
daffie commentedThe patch looks good to me. I do have some questions:
Comment #11
justachris commentedAdding Related issues:
#2229793: Installation - Database name gets escaped for creation, but not for settings
#2443839: Drupal does not install when auto-creating the MySQL database with special characters
Comment #12
justachris commentedUpdated Actual Behavior based on most recent HEAD
Comment #13
jeroentWrote my first test for Drupal. Patch attached.
Comment #14
jeroentWrong patch. This is the right one...
Comment #15
stefan.r commentedI don't see how creating a table has anything to do with having an invalid database name, shouldn't this have its own test and its own error message?
missing newline after the bracket
Comment #16
cilefen commentedWe need to think about #10-2, sqlite.
Comment #17
cilefen commented#15-1 That's not new to this patch.
Comment #20
stefan.r commented@cilefen yes it's arguable whether it's in scope here, but what is appended to the error message is new. So if possible it would still be good if we could fix this here instead of making that error message even longer and more confusing...
Comment #21
cilefen commentedI have not thought about this issue in a while. From what I understand from looking at the surrounding code is that a table create is the ultimate test of whether the database is *really* ready. This patch could maybe do a better job of handling the exceptions as they bubble up.
Comment #22
jeroent15.2: Fixed.
Patch attached.
Comment #24
JulienD commentedClosing the issue because an older one is already existing #2443839
I have summarized patches and conversations over there