fix(upgrade): ignore whitespace around root user values before quoting

phpdotenv trims whitespace around an unquoted value, including the \r of
CRLF line endings. The repair quoted such values, which broke valid lines in
CRLF files and kept spaces that phpdotenv drops. Trim the value first and
quote it only when a space is still inside it.

Closes #12375

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Andras Bacsai
2026-10-29 18:28:14 +01:00
co-authored by Claude Opus 5.5
parent 43933ee6cc
commit 7faa46bbd4
3 changed files with 18 additions and 0 deletions
+3
View File
@@ -228,6 +228,9 @@ quote_root_user_env_values() {
local key value
for key in ROOT_USERNAME ROOT_USER_EMAIL ROOT_USER_PASSWORD; do
value=$(grep -m1 "^${key}=" "$ENV_FILE" | cut -d '=' -f2-) || continue
# phpdotenv ignores whitespace around an unquoted value (also the \r of CRLF line endings)
value="${value#"${value%%[![:space:]]*}"}"
value="${value%"${value##*[![:space:]]}"}"
case "$value" in
\"* | \'* | *[[:space:]]\#*) continue ;;
*[[:space:]]*) ;;
+3
View File
@@ -228,6 +228,9 @@ quote_root_user_env_values() {
local key value
for key in ROOT_USERNAME ROOT_USER_EMAIL ROOT_USER_PASSWORD; do
value=$(grep -m1 "^${key}=" "$ENV_FILE" | cut -d '=' -f2-) || continue
# phpdotenv ignores whitespace around an unquoted value (also the \r of CRLF line endings)
value="${value#"${value%%[![:space:]]*}"}"
value="${value%"${value##*[![:space:]]}"}"
case "$value" in
\"* | \'* | *[[:space:]]\#*) continue ;;
*[[:space:]]*) ;;
@@ -65,3 +65,15 @@ it('keeps root user credentials that already parse unchanged', function (string
expect(repairRootUserEnvWithUpgradeScript($scriptPath, $initialEnv))->toBe($initialEnv);
})->with($upgradeScripts);
it('keeps root user credentials that only have whitespace around the value unchanged', function (string $scriptPath) {
$initialEnv = "ROOT_USER_EMAIL=admin@example.com\r\nROOT_USERNAME= Jane\r\nROOT_USER_PASSWORD=Secret1! \r\nAPP_ENV=production\r\n";
expect(repairRootUserEnvWithUpgradeScript($scriptPath, $initialEnv))->toBe($initialEnv);
})->with($upgradeScripts);
it('quotes a root username with spaces in a file with CRLF line endings', function (string $scriptPath) {
$env = repairRootUserEnvWithUpgradeScript($scriptPath, "ROOT_USERNAME=Jane Doe\r\nAPP_ENV=production\r\n");
expect(Dotenv::parse($env))->toBe(['ROOT_USERNAME' => 'Jane Doe', 'APP_ENV' => 'production']);
})->with($upgradeScripts);