Skip to content

Commit f271654

Browse files
committed
Merge branch '4.3' into 4.4
* 4.3: fix PHP 5.6 compatibility [Cache] fixed TagAwareAdapter returning invalid cache Add plus character `+` to legal mime subtype Make Symfony\Contracts\Service\Test\ServiceLocatorTest abstract bug #33942 [DI] Add extra type check to php dumper [Dotenv] search variable values in ENV first then env file [PropertyInfo] Respect property name case when guessing from public method name [VarDumper] fix resetting the "bold" state in CliDumper Missing argument in method_exists SCA: added missing break in a loop
2 parents ea43247 + f8b4f43 commit f271654

File tree

3 files changed

+42
-14
lines changed

3 files changed

+42
-14
lines changed

Dotenv.php

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,8 @@ private function lexValue(): string
257257
throw $this->createFormatException('Whitespace are not supported before the value');
258258
}
259259

260+
$loadedVars = array_flip(explode(',', isset($_SERVER['SYMFONY_DOTENV_VARS']) ? $_SERVER['SYMFONY_DOTENV_VARS'] : (isset($_ENV['SYMFONY_DOTENV_VARS']) ? $_ENV['SYMFONY_DOTENV_VARS'] : '')));
261+
unset($loadedVars['']);
260262
$v = '';
261263

262264
do {
@@ -295,8 +297,8 @@ private function lexValue(): string
295297
++$this->cursor;
296298
$value = str_replace(['\\"', '\r', '\n'], ['"', "\r", "\n"], $value);
297299
$resolvedValue = $value;
298-
$resolvedValue = $this->resolveVariables($resolvedValue);
299-
$resolvedValue = $this->resolveCommands($resolvedValue);
300+
$resolvedValue = $this->resolveVariables($resolvedValue, $loadedVars);
301+
$resolvedValue = $this->resolveCommands($resolvedValue, $loadedVars);
300302
$resolvedValue = str_replace('\\\\', '\\', $resolvedValue);
301303
$v .= $resolvedValue;
302304
} else {
@@ -318,8 +320,8 @@ private function lexValue(): string
318320
}
319321
$value = rtrim($value);
320322
$resolvedValue = $value;
321-
$resolvedValue = $this->resolveVariables($resolvedValue);
322-
$resolvedValue = $this->resolveCommands($resolvedValue);
323+
$resolvedValue = $this->resolveVariables($resolvedValue, $loadedVars);
324+
$resolvedValue = $this->resolveCommands($resolvedValue, $loadedVars);
323325
$resolvedValue = str_replace('\\\\', '\\', $resolvedValue);
324326

325327
if ($resolvedValue === $value && preg_match('/\s+/', $value)) {
@@ -372,7 +374,7 @@ private function skipEmptyLines()
372374
}
373375
}
374376

375-
private function resolveCommands(string $value): string
377+
private function resolveCommands(string $value, array $loadedVars): string
376378
{
377379
if (false === strpos($value, '$')) {
378380
return $value;
@@ -388,7 +390,7 @@ private function resolveCommands(string $value): string
388390
)
389391
/x';
390392

391-
return preg_replace_callback($regex, function ($matches) {
393+
return preg_replace_callback($regex, function ($matches) use ($loadedVars) {
392394
if ('\\' === $matches[1]) {
393395
return substr($matches[0], 1);
394396
}
@@ -408,7 +410,14 @@ private function resolveCommands(string $value): string
408410
$process->inheritEnvironmentVariables();
409411
}
410412

411-
$process->setEnv($this->values);
413+
$env = [];
414+
foreach ($this->values as $name => $value) {
415+
if (isset($loadedVars[$name]) || (!isset($_ENV[$name]) && !(isset($_SERVER[$name]) && 0 !== strpos($name, 'HTTP_')))) {
416+
$env[$name] = $value;
417+
}
418+
}
419+
$process->setEnv($env);
420+
412421
try {
413422
$process->mustRun();
414423
} catch (ProcessException $e) {
@@ -419,7 +428,7 @@ private function resolveCommands(string $value): string
419428
}, $value);
420429
}
421430

422-
private function resolveVariables(string $value): string
431+
private function resolveVariables(string $value, array $loadedVars): string
423432
{
424433
if (false === strpos($value, '$')) {
425434
return $value;
@@ -436,7 +445,7 @@ private function resolveVariables(string $value): string
436445
(?P<closing_brace>\})? # optional closing brace
437446
/x';
438447

439-
$value = preg_replace_callback($regex, function ($matches) {
448+
$value = preg_replace_callback($regex, function ($matches) use ($loadedVars) {
440449
// odd number of backslashes means the $ character is escaped
441450
if (1 === \strlen($matches['backslashes']) % 2) {
442451
return substr($matches[0], 1);
@@ -452,14 +461,16 @@ private function resolveVariables(string $value): string
452461
}
453462

454463
$name = $matches['name'];
455-
if (isset($this->values[$name])) {
464+
if (isset($loadedVars[$name]) && isset($this->values[$name])) {
456465
$value = $this->values[$name];
457-
} elseif (isset($_SERVER[$name]) && 0 !== strpos($name, 'HTTP_')) {
458-
$value = $_SERVER[$name];
459466
} elseif (isset($_ENV[$name])) {
460467
$value = $_ENV[$name];
468+
} elseif (isset($_SERVER[$name]) && 0 !== strpos($name, 'HTTP_')) {
469+
$value = $_SERVER[$name];
470+
} elseif (isset($this->values[$name])) {
471+
$value = $this->values[$name];
461472
} else {
462-
$value = (string) getenv($name);
473+
$value = '';
463474
}
464475

465476
if ('' === $value && isset($matches['default_value'])) {

Tests/DotenvTest.php

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ public function testParse($data, $expected)
7272
public function getEnvData()
7373
{
7474
putenv('LOCAL=local');
75+
$_ENV['LOCAL'] = 'local';
7576
$_ENV['REMOTE'] = 'remote';
7677
$_SERVER['SERVERVAR'] = 'servervar';
7778

@@ -424,6 +425,22 @@ public function testOverridingEnvVarsWithNamesMemorizedInSpecialVar()
424425
$this->assertSame('/var/www', getenv('DOCUMENT_ROOT'));
425426
}
426427

428+
public function testGetVariablesValueFromEnvFirst()
429+
{
430+
$_ENV['APP_ENV'] = 'prod';
431+
$dotenv = new Dotenv(true);
432+
433+
$test = "APP_ENV=dev\nTEST1=foo1_\${APP_ENV}";
434+
$values = $dotenv->parse($test);
435+
$this->assertSame('foo1_prod', $values['TEST1']);
436+
437+
if ('\\' !== \DIRECTORY_SEPARATOR) {
438+
$test = "APP_ENV=dev\nTEST2=foo2_\$(php -r 'echo \$_SERVER[\"APP_ENV\"];')";
439+
$values = $dotenv->parse($test);
440+
$this->assertSame('foo2_prod', $values['TEST2']);
441+
}
442+
}
443+
427444
/**
428445
* @group legacy
429446
* @expectedDeprecation The default value of "$usePutenv" argument of "%s" will be changed from "true" to "false" in Symfony 5.0. You should define its value explicitly.

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
"php": "^7.1.3"
2020
},
2121
"require-dev": {
22-
"symfony/process": "^3.4|^4.0|^5.0"
22+
"symfony/process": "^3.4.2|^4.0|^5.0"
2323
},
2424
"autoload": {
2525
"psr-4": { "Symfony\\Component\\Dotenv\\": "" },

0 commit comments

Comments
 (0)