bug #21776 [Process] Fix ignoring of bad env var names (nicolas-grekas)

This PR was merged into the 3.2 branch.

Discussion
----------

[Process] Fix ignoring of bad env var names

| Q             | A
| ------------- | ---
| Branch?       | 3.2
| Bug fix?      | yes
| New feature?  | no
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | #21704
| License       | MIT
| Doc PR        | -

Patch backported from master, which is free from the linked issue.

Commits
-------

406bb09ae3 [Process] Fix ignoring of bad env var names
This commit is contained in:
Fabien Potencier 2017-02-27 13:33:35 -08:00
commit 6d39fd4d51
2 changed files with 27 additions and 15 deletions

View File

@ -266,24 +266,25 @@ class Process implements \IteratorAggregate
$this->callback = $this->buildCallback($callback);
$this->hasCallback = null !== $callback;
$descriptors = $this->getDescriptors();
$inheritEnv = $this->inheritEnv;
$commandline = $this->commandline;
$envline = '';
if (null !== $this->env && $this->inheritEnv) {
$env = $this->env;
$envBackup = array();
if (null !== $env && $inheritEnv) {
if ('\\' === DIRECTORY_SEPARATOR && !empty($this->options['bypass_shell']) && !$this->enhanceWindowsCompatibility) {
throw new LogicException('The "bypass_shell" option must be false to inherit environment variables while enhanced Windows compatibility is off');
}
$env = '\\' === DIRECTORY_SEPARATOR ? '(SET %s)&&' : 'export %s;';
foreach ($this->env as $k => $v) {
$envline .= sprintf($env, ProcessUtils::escapeArgument("$k=$v"));
foreach ($env as $k => $v) {
$envBackup[$k] = getenv($v);
putenv(false === $v || null === $v ? $k : "$k=$v");
}
$env = null;
} else {
$env = $this->env;
}
if ('\\' === DIRECTORY_SEPARATOR && $this->enhanceWindowsCompatibility) {
$commandline = 'cmd /V:ON /E:ON /D /C "('.$envline.$commandline.')';
$commandline = 'cmd /V:ON /E:ON /D /C "('.$commandline.')';
foreach ($this->processPipes->getFiles() as $offset => $filename) {
$commandline .= ' '.$offset.'>'.ProcessUtils::escapeArgument($filename);
}
@ -297,18 +298,20 @@ class Process implements \IteratorAggregate
$descriptors[3] = array('pipe', 'w');
// See https://unix.stackexchange.com/questions/71205/background-process-pipe-input
$commandline = $envline.'{ ('.$this->commandline.') <&3 3<&- 3>/dev/null & } 3<&0;';
$commandline = '{ ('.$this->commandline.') <&3 3<&- 3>/dev/null & } 3<&0;';
$commandline .= 'pid=$!; echo $pid >&3; wait $pid; code=$?; echo $code >&3; exit $code';
// Workaround for the bug, when PTS functionality is enabled.
// @see : https://bugs.php.net/69442
$ptsWorkaround = fopen(__FILE__, 'r');
} elseif ('' !== $envline) {
$commandline = $envline.$commandline;
}
$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.');
}
@ -1104,10 +1107,7 @@ class Process implements \IteratorAggregate
return !is_array($value);
});
$this->env = array();
foreach ($env as $key => $value) {
$this->env[$key] = (string) $value;
}
$this->env = $env;
return $this;
}

View File

@ -1391,6 +1391,18 @@ class ProcessTest extends TestCase
$this->assertSame('456', $p2->getOutput());
}
public function testSetBadEnv()
{
$process = $this->getProcess('echo hello');
$process->setEnv(array('bad%%' => '123'));
$process->inheritEnvironmentVariables(true);
$process->run();
$this->assertSame('hello'.PHP_EOL, $process->getOutput());
$this->assertSame('', $process->getErrorOutput());
}
public function testInheritEnvEnabled()
{
$process = $this->getProcess(self::$phpBin.' -r '.escapeshellarg('echo serialize($_SERVER);'), null, array('BAR' => 'BAZ'));