Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit dab514c

Browse files
Merge branch '6.4' into 7.4
* 6.4: [VarExporter] Don't warn for __sleep()-listed uninitialized typed properties [Dotenv] Fix variable corruption when loading env more than once
2 parents 1ff1857 + ac4ed3d commit dab514c

2 files changed

Lines changed: 49 additions & 12 deletions

File tree

Dotenv.php

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ final class Dotenv
3737
private int $end;
3838
private array $values = [];
3939
private array $overriddenValues = [];
40+
private array $loadedRawVars = [];
4041
private array $prodEnvs = ['prod'];
4142
private bool $usePutenv = false;
4243

@@ -646,10 +647,16 @@ private function doLoad(bool $overrideExistingVars, array $paths): void
646647

647648
$values = $this->parseRaw($data, $path);
648649

650+
$loadedVars = array_flip(explode(',', $_SERVER['SYMFONY_DOTENV_VARS'] ?? $_ENV['SYMFONY_DOTENV_VARS'] ?? ''));
651+
unset($loadedVars['']);
652+
649653
foreach ($values as $name => $_) {
650654
if (!isset($this->overriddenValues[$name]) && isset($_ENV[$name])) {
651655
$this->overriddenValues[$name] = $_ENV[$name];
652656
}
657+
if (isset($loadedVars[$name]) || $overrideExistingVars || !isset($_ENV[$name])) {
658+
$this->loadedRawVars[$name] = true;
659+
}
653660
}
654661

655662
$this->populate($values, $overrideExistingVars);
@@ -705,6 +712,10 @@ private function resolveLoadedVars(): void
705712
$loadedVars = array_flip(explode(',', $_SERVER['SYMFONY_DOTENV_VARS'] ?? $_ENV['SYMFONY_DOTENV_VARS'] ?? ''));
706713
unset($loadedVars['']);
707714

715+
$rawVars = $this->loadedRawVars;
716+
$this->loadedRawVars = [];
717+
unset($rawVars['SYMFONY_DOTENV_VARS']);
718+
708719
$this->values = [];
709720
$this->path = '';
710721
$this->data = '';
@@ -716,10 +727,7 @@ private function resolveLoadedVars(): void
716727
// (e.g. MY_VAR="${MY_VAR:-default}") so their own raw value is hidden
717728
// during resolution, allowing the default to trigger correctly.
718729
$selfReferencingVars = [];
719-
foreach ($loadedVars as $name => $_) {
720-
if ('SYMFONY_DOTENV_VARS' === $name) {
721-
continue;
722-
}
730+
foreach ($rawVars as $name => $_) {
723731
$value = $_ENV[$name] ?? '';
724732
if (str_contains($value, '$') && preg_match('/\$\{?'.preg_quote($name, '/').'(?![A-Za-z0-9_])/', $value)) {
725733
$selfReferencingVars[$name] = true;
@@ -728,10 +736,7 @@ private function resolveLoadedVars(): void
728736

729737
for ($pass = 0; $pass < 5; ++$pass) {
730738
$resolved = [];
731-
foreach ($loadedVars as $name => $_) {
732-
if ('SYMFONY_DOTENV_VARS' === $name) {
733-
continue;
734-
}
739+
foreach ($rawVars as $name => $_) {
735740
if (!str_contains($value = $_ENV[$name] ?? '', '$')) {
736741
continue;
737742
}
@@ -785,10 +790,7 @@ private function resolveLoadedVars(): void
785790

786791
// Restore literal $ signs and unescape backslashes
787792
$restored = [];
788-
foreach ($loadedVars as $name => $_) {
789-
if ('SYMFONY_DOTENV_VARS' === $name) {
790-
continue;
791-
}
793+
foreach ($rawVars as $name => $_) {
792794
$value = $_ENV[$name] ?? '';
793795
if ($value !== $newValue = str_replace(["\x00", '\\\\'], ['$', '\\'], $value)) {
794796
$restored[$name] = $newValue;

Tests/DotenvTest.php

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,41 @@ public function testLoad()
235235
$this->assertSame('BAZ', $bar);
236236
}
237237

238+
public function testLoadDoesNotReResolveAlreadyLoadedVars()
239+
{
240+
unset($_ENV['FOO'], $_ENV['BAR'], $_ENV['SYMFONY_DOTENV_VARS']);
241+
unset($_SERVER['FOO'], $_SERVER['BAR'], $_SERVER['SYMFONY_DOTENV_VARS']);
242+
putenv('FOO');
243+
putenv('BAR');
244+
putenv('SYMFONY_DOTENV_VARS');
245+
246+
@mkdir($tmpdir = sys_get_temp_dir().'/dotenv');
247+
248+
$path1 = tempnam($tmpdir, 'sf-');
249+
$path2 = tempnam($tmpdir, 'sf-');
250+
251+
file_put_contents($path1, "FOO='This\$isokay'");
252+
file_put_contents($path2, "BAR='hello'");
253+
254+
try {
255+
(new Dotenv())->load($path1);
256+
$this->assertSame('This$isokay', $_ENV['FOO']);
257+
258+
(new Dotenv())->load($path2);
259+
$this->assertSame('This$isokay', $_ENV['FOO']);
260+
$this->assertSame('hello', $_ENV['BAR']);
261+
} finally {
262+
unset($_ENV['FOO'], $_ENV['BAR'], $_ENV['SYMFONY_DOTENV_VARS']);
263+
unset($_SERVER['FOO'], $_SERVER['BAR'], $_SERVER['SYMFONY_DOTENV_VARS']);
264+
putenv('FOO');
265+
putenv('BAR');
266+
putenv('SYMFONY_DOTENV_VARS');
267+
unlink($path1);
268+
unlink($path2);
269+
rmdir($tmpdir);
270+
}
271+
}
272+
238273
public function testLoadEnv()
239274
{
240275
$resetContext = static function (): void {

0 commit comments

Comments
 (0)