Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DsnParser accepts a quoted DSN #6789

Open
TimWolla opened this issue Feb 17, 2025 · 2 comments
Open

DsnParser accepts a quoted DSN #6789

TimWolla opened this issue Feb 17, 2025 · 2 comments

Comments

@TimWolla
Copy link

This request is halfway between a bug report and a feature request. That's why I am not strictly following either template:

A few days ago I had a hard to debug issue when setting up a new Symfony application. In the Symfony Doctrine config I used an environment variable as the source for the DBAL URL:

doctrine:
    dbal:
        url: '%env(resolve:DATABASE_URL)%'

The DATABASE_URL was configured as:

DATABASE_URL="sqlite:///%kernel.project_dir%/var/data.db"

What I did not realize was that the tool I used to configure the environment variables includes the double quotes " as-is in the value of the environment variable.

As a result internally the DSN was interpreted as if the following code was used:

$dsnParser = new DsnParser();
var_dump($dsnParser->parse('"sqlite:///tmp/data.db"'));

which results in the following output:

array(1) {
  ["dbname"]=>
  string(22) "sqlite:///tmp/data.db""
}

As a result, Symfony / DBAL attempted to use the pdo_mysql driver with the dbname of sqlite:////path/to/symfony/application/var/data.db".

It took me quite some time of debugging through Symfony’s Doctrine integration and DBAL itself to find the issue. It did not help that the resulting dbname did not include the leading quote, but only the trailing one, since the string looks correct at a first glance.


As to what I expect here: The ideal solution would probably be throwing a MalformedDsnException if the DSN is surrounded by double or single quotes, since this likely indicates some user error rather than a valid DB name.

Alternatively, the following change probably would've simplified the debugging for me, because it would not have stripped the leading quote from the resulting dbname, making it more obvious that something is wrong:

--- i/src/Tools/DsnParser.php
+++ w/src/Tools/DsnParser.php
@@ -132,7 +132,7 @@ final class DsnParser
     private function normalizeDatabaseUrlPath(string $urlPath): string
     {
         // Trim leading slash from URL path.
-        return substr($urlPath, 1);
+        return preg_replace('/^\//', '', $urlPath);
     }
 
     /**

I'm leaving the choice of what to do to you as the maintainer. If you decide not to change anything, that's also fine with me. I simply wanted to write this down somewhere in case there is something to improve and also for search engines to come across, possibly helping someone having the same issue.

@derrabus
Copy link
Member

The main problem is that we accept incomplete DSNs in the parser. Otherwise, we could just make it throw if the scheme is missing. Maybe we should consider rejecting incomplete DSNs for 5.0.

About your proposed change, please send a PR. It looks like a bugfix to me.

TimWolla added a commit to TimWolla/doctrine-dbal that referenced this issue Feb 17, 2025
Previously the DsnParser unconditionally removed the first character from the
path, without verifying that it is actually a slash and that it is dealing with
a reasonably well-formed URI. This causes confusing behavior when a malformed
URI that survives `parse_url()` is passed to `parse()`, since DsnParser would
return the input as the `dbname`, but with the first character missing.

This can lead to hard-to-debug situations when the DSN is coming from an
environment variable, where quoting characters are accidentally included in the
value itself, instead of being interpreted by the tool setting the env, since
the `dbname` almost looks like the intended input (but still having the
trailing quote).

see doctrine#6789
@TimWolla
Copy link
Author

About your proposed change, please send a PR. It looks like a bugfix to me.

Thanks: #6790. I've also included a check for the host, since we likely also don't want to strip leading slashes if an incomplete URI is passed.

TimWolla added a commit to TimWolla/doctrine-dbal that referenced this issue Feb 17, 2025
Previously the DsnParser unconditionally removed the first character from the
path, without verifying that it is actually a slash and that it is dealing with
a reasonably well-formed URI. This causes confusing behavior when a malformed
URI that survives `parse_url()` is passed to `parse()`, since DsnParser would
return the input as the `dbname`, but with the first character missing.

This can lead to hard-to-debug situations when the DSN is coming from an
environment variable, where quoting characters are accidentally included in the
value itself, instead of being interpreted by the tool setting the env, since
the `dbname` almost looks like the intended input (but still having the
trailing quote).

see doctrine#6789
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants