From ef632ec721ac6c908d6228d24299716cd1ec21a7 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Sun, 10 Dec 2017 10:47:05 +0100 Subject: [PATCH] [Process] Dont rely on putenv(), it fails on ZTS PHP --- src/Symfony/Component/BrowserKit/Client.php | 1 + src/Symfony/Component/Process/Process.php | 50 +++++++++++-------- .../Component/Process/Tests/ProcessTest.php | 12 +++++ 3 files changed, 43 insertions(+), 20 deletions(-) diff --git a/src/Symfony/Component/BrowserKit/Client.php b/src/Symfony/Component/BrowserKit/Client.php index 681bf697ef499..26e151e43d9f1 100644 --- a/src/Symfony/Component/BrowserKit/Client.php +++ b/src/Symfony/Component/BrowserKit/Client.php @@ -343,6 +343,7 @@ protected function doRequestInProcess($request) { $deprecationsFile = tempnam(sys_get_temp_dir(), 'deprec'); putenv('SYMFONY_DEPRECATIONS_SERIALIZE='.$deprecationsFile); + $_ENV['SYMFONY_DEPRECATIONS_SERIALIZE'] = $deprecationsFile; $process = new PhpProcess($this->getScript($request), null, null); $process->run(); diff --git a/src/Symfony/Component/Process/Process.php b/src/Symfony/Component/Process/Process.php index 3d5ab7d8ff10e..4087dabc14770 100644 --- a/src/Symfony/Component/Process/Process.php +++ b/src/Symfony/Component/Process/Process.php @@ -304,19 +304,16 @@ public function start(callable $callback = null/*, array $env = array()*/) $inheritEnv = true; } - $envBackup = array(); if (null !== $env && $inheritEnv) { - foreach ($env as $k => $v) { - $envBackup[$k] = getenv($k); - putenv(false === $v || null === $v ? $k : "$k=$v"); - } - $env = null; + $env += $this->getDefaultEnv(); } elseif (null !== $env) { @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); + } else { + $env = $this->getDefaultEnv(); } if ('\\' === DIRECTORY_SEPARATOR && $this->enhanceWindowsCompatibility) { $this->options['bypass_shell'] = true; - $commandline = $this->prepareWindowsCommandLine($commandline, $envBackup, $env); + $commandline = $this->prepareWindowsCommandLine($commandline, $env); } elseif (!$this->useFileHandles && $this->enhanceSigchildCompatibility && $this->isSigchildEnabled()) { // last exit code is output on the fourth pipe and caught to work around --enable-sigchild $descriptors[3] = array('pipe', 'w'); @@ -332,10 +329,6 @@ public function start(callable $callback = null/*, array $env = array()*/) $this->process = proc_open($commandline, $descriptors, $this->processPipes->pipes, $this->cwd, $env, $this->options); - foreach ($envBackup as $k => $v) { - putenv(false === $v ? $k : "$k=$v"); - } - if (!is_resource($this->process)) { throw new RuntimeException('Unable to launch a new process.'); } @@ -1623,7 +1616,7 @@ private function doSignal($signal, $throwException) return true; } - private function prepareWindowsCommandLine($cmd, array &$envBackup, array &$env = null) + private function prepareWindowsCommandLine($cmd, array &$env) { $uid = uniqid('', true); $varCount = 0; @@ -1636,7 +1629,7 @@ private function prepareWindowsCommandLine($cmd, array &$envBackup, array &$env [^"%!^]*+ )++ ) | [^"]*+ )"/x', - function ($m) use (&$envBackup, &$env, &$varCache, &$varCount, $uid) { + function ($m) use (&$env, &$varCache, &$varCount, $uid) { if (!isset($m[1])) { return $m[0]; } @@ -1654,13 +1647,7 @@ function ($m) use (&$envBackup, &$env, &$varCache, &$varCount, $uid) { $value = '"'.preg_replace('/(\\\\*)"/', '$1$1\\"', $value).'"'; $var = $uid.++$varCount; - if (null === $env) { - putenv("$var=$value"); - } else { - $env[$var] = $value; - } - - $envBackup[$var] = false; + $env[$var] = $value; return $varCache[$m[0]] = '!'.$var.'!'; }, @@ -1728,4 +1715,27 @@ private function escapeArgument($argument) return '"'.str_replace(array('"', '^', '%', '!', "\n"), array('""', '"^^"', '"^%"', '"^!"', '!LF!'), $argument).'"'; } + + private function getDefaultEnv() + { + if (\PHP_VERSION_ID >= 70100) { + $env = getenv(); + } else { + $env = array(); + + foreach ($_SERVER as $k => $v) { + if (is_string($v) && false !== $v = getenv($k)) { + $env[$k] = $v; + } + } + } + + foreach ($_ENV as $k => $v) { + if (is_string($v)) { + $env[$k] = $v; + } + } + + return $env; + } } diff --git a/src/Symfony/Component/Process/Tests/ProcessTest.php b/src/Symfony/Component/Process/Tests/ProcessTest.php index b73a5fa1660ee..c8bf33df8f0d0 100644 --- a/src/Symfony/Component/Process/Tests/ProcessTest.php +++ b/src/Symfony/Component/Process/Tests/ProcessTest.php @@ -1406,6 +1406,7 @@ public function testSetBadEnv() public function testEnvBackupDoesNotDeleteExistingVars() { putenv('existing_var=foo'); + $_ENV['existing_var'] = 'foo'; $process = $this->getProcess('php -r "echo getenv(\'new_test_var\');"'); $process->setEnv(array('existing_var' => 'bar', 'new_test_var' => 'foo')); $process->inheritEnvironmentVariables(); @@ -1415,6 +1416,9 @@ public function testEnvBackupDoesNotDeleteExistingVars() $this->assertSame('foo', $process->getOutput()); $this->assertSame('foo', getenv('existing_var')); $this->assertFalse(getenv('new_test_var')); + + putenv('existing_var'); + unset($_ENV['existing_var']); } public function testEnvIsInherited() @@ -1422,6 +1426,7 @@ public function testEnvIsInherited() $process = $this->getProcessForCode('echo serialize($_SERVER);', null, array('BAR' => 'BAZ')); putenv('FOO=BAR'); + $_ENV['FOO'] = 'BAR'; $process->run(); @@ -1429,6 +1434,9 @@ public function testEnvIsInherited() $env = array_intersect_key(unserialize($process->getOutput()), $expected); $this->assertEquals($expected, $env); + + putenv('FOO'); + unset($_ENV['FOO']); } /** @@ -1439,6 +1447,7 @@ public function testInheritEnvDisabled() $process = $this->getProcessForCode('echo serialize($_SERVER);', null, array('BAR' => 'BAZ')); putenv('FOO=BAR'); + $_ENV['FOO'] = 'BAR'; $this->assertSame($process, $process->inheritEnvironmentVariables(false)); $this->assertFalse($process->areEnvironmentVariablesInherited()); @@ -1450,6 +1459,9 @@ public function testInheritEnvDisabled() unset($expected['FOO']); $this->assertSame($expected, $env); + + putenv('FOO'); + unset($_ENV['FOO']); } public function testGetCommandLine() pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy