8000 bug #25417 [Process] Dont rely on putenv(), it fails on ZTS PHP (nico… · symfony/symfony@9fda6af · GitHub
[go: up one dir, main page]

Skip to content

Commit 9fda6af

Browse files
committed
bug #25417 [Process] Dont rely on putenv(), it fails on ZTS PHP (nicolas-grekas)
This PR was merged into the 3.3 branch. Discussion ---------- [Process] Dont rely on putenv(), it fails on ZTS PHP | Q | A | ------------- | --- | Branch? | 3.3 | Bug fix? | yes | New feature? | no | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | #24924 | License | MIT | Doc PR | - `putenv()` is not thread safe, but ZTS is PHP defaults on Windows. Commits ------- ef632ec [Process] Dont rely on putenv(), it fails on ZTS PHP
2 parents f744236 + ef632ec commit 9fda6af

File tree

3 files changed

+43
-20
lines changed

3 files changed

+43
-20
lines changed

src/Symfony/Component/BrowserKit/Client.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -343,6 +343,7 @@ protected function doRequestInProcess($request)
343343
{
344344
$deprecationsFile = tempnam(sys_get_temp_dir(), 'deprec');
345345
putenv('SYMFONY_DEPRECATIONS_SERIALIZE='.$deprecationsFile);
346+
$_ENV['SYMFONY_DEPRECATIONS_SERIALIZE'] = $deprecationsFile;
346347
$process = new PhpProcess($this->getScript($request), null, null);
347348
$process->run();
348349

src/Symfony/Component/Process/Process.php

Lines changed: 30 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -304,19 +304,16 @@ public function start(callable $callback = null/*, array $env = array()*/)
304304
$inheritEnv = true;
305305
}
306306

307-
$envBackup = array();
308307
if (null !== $env && $inheritEnv) {
309-
foreach ($env as $k => $v) {
310-
$envBackup[$k] = getenv($k);
311-
putenv(false === $v || null === $v ? $k : "$k=$v");
312-
}
313-
$env = null;
308+
$env += $this->getDefaultEnv();
314309
} elseif (null !== $env) {
315310
@trigger_error('Not inheriting environment variables is deprecated since Symfony 3.3 and will always happen in 4.0. Set "Process::inheritEnvironmentVariables()" to true instead.', E_USER_DEPRECATED);
311+
} else {
312+
$env = $this->getDefaultEnv();
316313
}
317314
if ('\\' === DIRECTORY_SEPARATOR && $this->enhanceWindowsCompatibility) {
318315
$this->options['bypass_shell'] = true;
319-
$commandline = $this->prepareWindowsCommandLine($commandline, $envBackup, $env);
316+
$commandline = $this->prepareWindowsCommandLine($commandline, $env);
320317
} elseif (!$this->useFileHandles && $this->enhanceSigchildCompatibility && $this->isSigchildEnabled()) {
321318
// last exit code is output on the fourth pipe and caught to work around --enable-sigchild
322319
$descriptors[3] = array('pipe', 'w');
@@ -332,10 +329,6 @@ public function start(callable $callback = null/*, array $env = array()*/)
332329

333330
$this->process = proc_open($commandline, $descriptors, $this->processPipes->pipes, $this->cwd, $env, $this->options);
334331

335-
foreach ($envBackup as $k => $v) {
336-
putenv(false === $v ? $k : "$k=$v");
337-
}
338-
339332
if (!is_resource($this->process)) {
340333
throw new RuntimeException('Unable to launch a new process.');
341334
}
@@ -1623,7 +1616,7 @@ private function doSignal($signal, $throwException)
16231616
return true;
16241617
}
16251618

1626-
private function prepareWindowsCommandLine($cmd, array &$envBackup, array &$env = null)
1619+
private function prepareWindowsCommandLine($cmd, array &$env)
16271620
{
16281621
$uid = uniqid('', true);
16291622
$varCount = 0;
@@ -1636,7 +1629,7 @@ private function prepareWindowsCommandLine($cmd, array &$envBackup, array &$env
16361629
[^"%!^]*+
16371630
)++
16381631
) | [^"]*+ )"/x',
1639-
function ($m) use (&$envBackup, &$env, &$varCache, &$varCount, $uid) {
1632+
function ($m) use (&$env, &$varCache, &$varCount, $uid) {
16401633
if (!isset($m[1])) {
16411634
return $m[0];
16421635
}
@@ -1654,13 +1647,7 @@ function ($m) use (&$envBackup, &$env, &$varCache, &$varCount, $uid) {
16541647
$value = '"'.preg_replace('/(\\\\*)"/', '$1$1\\"', $value).'"';
16551648
$var = $uid.++$varCount;
16561649

1657-
if (null === $env) {
1658-
putenv("$var=$value");
1659-
} else {
1660-
$env[$var] = $value;
1661-
}
1662-
1663-
$envBackup[$var] = false;
1650+
$env[$var] = $value;
16641651

16651652
return $varCache[$m[0]] = '!'.$var.'!';
16661653
},
@@ -1728,4 +1715,27 @@ private function escapeArgument($argument)
17281715

17291716
return '"'.str_replace(array('"', '^', '%', '!', "\n"), array('""', '"^^"', '"^%"', '"^!"', '!LF!'), $argument).'"';
17301717
}
1718+
1719+
private function getDefaultEnv()
1720+
{
1721+
if (\PHP_VERSION_ID >= 70100) {
1722+
$env = getenv();
1723+
} else {
1724+
$env = array();
1725+
1726+
foreach ($_SERVER as $k => $v) {
1727+
if (is_string($v) && false !== $v = getenv($k)) {
1728+
$env[$k] = $v;
1729+
}
1730+
}
1731+
}
1732+
1733+
foreach ($_ENV as $k => $v) {
1734+
if (is_string($v)) {
1735+
$env[$k] = $v;
1736+
}
1737+
}
1738+
1739+
return $env;
1740+
}
17311741
}

src/Symfony/Component/Process/Tests/ProcessTest.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1406,6 +1406,7 @@ public function testSetBadEnv()
14061406
public function testEnvBackupDoesNotDeleteExistingVars()
14071407
{
14081408
putenv('existing_var=foo');
1409+
$_ENV['existing_var'] = 'foo';
14091410
$process = $this->getProcess('php -r "echo getenv(\'new_test_var\');"');
14101411
$process->setEnv(array('existing_var' => 'bar', 'new_test_var' => 'foo'));
14111412
$process->inheritEnvironmentVariables();
@@ -1415,20 +1416,27 @@ public function testEnvBackupDoesNotDeleteExistingVars()
14151416
$this->assertSame('foo', $process->getOutput());
14161417
$this->assertSame('foo', getenv('existing_var'));
14171418
$this->assertFalse(getenv('new_test_var'));
1419+
1420+
putenv('existing_var');
1421+
unset($_ENV['existing_var']);
14181422
}
14191423

14201424
public function testEnvIsInherited()
14211425
{
14221426
$process = $this->getProcessForCode('echo serialize($_SERVER);', null, array('BAR' => 'BAZ'));
14231427

14241428
putenv('FOO=BAR');
1429+
$_ENV['FOO'] = 'BAR';
14251430

14261431
$process->run();
14271432

14281433
$expected = array('BAR' => 'BAZ', 'FOO' => 'BAR');
14291434
$env = array_intersect_key(unserialize($process->getOutput()), $expected);
14301435

14311436
$this->assertEquals($expected, $env);
1437+
1438+
putenv('FOO');
1439+
unset($_ENV['FOO']);
14321440
}
14331441

14341442
/**
@@ -1439,6 +1447,7 @@ public function testInheritEnvDisabled()
14391447
$process = $this->getProcessForCode('echo serialize($_SERVER);', null, array('BAR' => 'BAZ'));
14401448

14411449
putenv('FOO=BAR');
1450+
$_ENV['FOO'] = 'BAR';
14421451

14431452
$this->assertSame($process, $process->inheritEnvironmentVariables(false));
14441453
$this->assertFalse($process->areEnvironmentVariablesInherited());
@@ -1450,6 +1459,9 @@ public function testInheritEnvDisabled()
14501459
unset($expected['FOO']);
14511460

14521461
$this->assertSame($expected, $env);
1462+
1463+
putenv('FOO');
1464+
unset($_ENV['FOO']);
14531465
}
14541466

14551467
public function testGetCommandLine()

0 commit comments

Comments
 (0)
0