From 26032ef055ad6a7c3d5bb7ca8bb4b5b610ca50a8 Mon Sep 17 00:00:00 2001 From: maryo Date: Tue, 2 May 2017 20:18:44 +0200 Subject: [PATCH] [Process] Fixed incorrectly escaping arguments on Windows when inheritEnvironmentVariables is set to false --- src/Symfony/Component/Process/Process.php | 17 +++++++++++------ .../Component/Process/Tests/ProcessTest.php | 13 +++++++++++++ 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/src/Symfony/Component/Process/Process.php b/src/Symfony/Component/Process/Process.php index a709f4a61d..fb12d393ab 100644 --- a/src/Symfony/Component/Process/Process.php +++ b/src/Symfony/Component/Process/Process.php @@ -320,7 +320,7 @@ class Process implements \IteratorAggregate } if ('\\' === DIRECTORY_SEPARATOR && $this->enhanceWindowsCompatibility) { $this->options['bypass_shell'] = true; - $commandline = $this->prepareWindowsCommandLine($commandline, $envBackup); + $commandline = $this->prepareWindowsCommandLine($commandline, $envBackup, $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'); @@ -1627,7 +1627,7 @@ class Process implements \IteratorAggregate return true; } - private function prepareWindowsCommandLine($cmd, array &$envBackup) + private function prepareWindowsCommandLine($cmd, array &$envBackup, array &$env = null) { $uid = uniqid('', true); $varCount = 0; @@ -1640,7 +1640,7 @@ class Process implements \IteratorAggregate [^"%!^]*+ )++ )"/x', - function ($m) use (&$envBackup, &$varCache, &$varCount, $uid) { + function ($m) use (&$envBackup, &$env, &$varCache, &$varCount, $uid) { if (isset($varCache[$m[0]])) { return $varCache[$m[0]]; } @@ -1652,10 +1652,15 @@ class Process implements \IteratorAggregate } $value = str_replace(array('!LF!', '"^!"', '"^%"', '"^^"', '""'), array("\n", '!', '%', '^', '"'), $value); - $value = preg_replace('/(\\\\*)"/', '$1$1\\"', $value); - + $value = '"'.preg_replace('/(\\\\*)"/', '$1$1\\"', $value).'"'; $var = $uid.++$varCount; - putenv("$var=\"$value\""); + + if (null === $env) { + putenv("$var=$value"); + } else { + $env[$var] = $value; + } + $envBackup[$var] = false; return $varCache[$m[0]] = '!'.$var.'!'; diff --git a/src/Symfony/Component/Process/Tests/ProcessTest.php b/src/Symfony/Component/Process/Tests/ProcessTest.php index 642df9c4a3..ade11138e3 100644 --- a/src/Symfony/Component/Process/Tests/ProcessTest.php +++ b/src/Symfony/Component/Process/Tests/ProcessTest.php @@ -1465,6 +1465,19 @@ class ProcessTest extends TestCase $this->assertSame($arg, $p->getOutput()); } + /** + * @dataProvider provideEscapeArgument + * @group legacy + */ + public function testEscapeArgumentWhenInheritEnvDisabled($arg) + { + $p = new Process(array(self::$phpBin, '-r', 'echo $argv[1];', $arg), null, array('BAR' => 'BAZ')); + $p->inheritEnvironmentVariables(false); + $p->run(); + + $this->assertSame($arg, $p->getOutput()); + } + public function provideEscapeArgument() { yield array('a"b%c%');