Skip to content

Commit

Permalink
feature #26372 Revert "feature #24763 [Process] Allow writing portabl…
Browse files Browse the repository at this point in the history
…e "prepared" command lines (Simperfit)" (nicolas-grekas)

This PR was merged into the 4.1-dev branch.

Discussion
----------

Revert "feature #24763 [Process] Allow writing portable "prepared" command lines (Simperfit)"

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

This reverts commit 1364089, reversing
changes made to e043478.

As discussed in #24763 and #26344

This doens't revert the possibility to use prepared command lines. They just won't be *portable* anymore, unless special care is taken by "userland".
Ie the placeholders need to be shell-dependent: use eg `echo "$FOO"` on *nix (the double quotes *are* important), and `echo !FOO!` on Windows (no double quotes there).

Commits
-------

6a98bfa Revert "feature #24763 [Process] Allow writing portable "prepared" command lines (Simperfit)"
  • Loading branch information
fabpot committed Mar 5, 2018
2 parents 7a9929f + 6a98bfa commit d65c43b
Show file tree
Hide file tree
Showing 2 changed files with 3 additions and 57 deletions.
32 changes: 3 additions & 29 deletions src/Symfony/Component/Process/Process.php
Expand Up @@ -258,21 +258,18 @@ public function start(callable $callback = null, array $env = array())
$this->hasCallback = null !== $callback;
$descriptors = $this->getDescriptors();

if ($this->env) {
$env += $this->env;
}

if (is_array($commandline = $this->commandline)) {
$commandline = implode(' ', array_map(array($this, 'escapeArgument'), $commandline));

if ('\\' !== DIRECTORY_SEPARATOR) {
// exec is mandatory to deal with sending a signal to the process
$commandline = 'exec '.$commandline;
}
} else {
$commandline = $this->replacePlaceholders($commandline, $env);
}

if ($this->env) {
$env += $this->env;
}
$env += $this->getDefaultEnv();

$options = array('suppress_errors' => true);
Expand Down Expand Up @@ -1552,29 +1549,6 @@ private function escapeArgument(string $argument): string
return '"'.str_replace(array('"', '^', '%', '!', "\n"), array('""', '"^^"', '"^%"', '"^!"', '!LF!'), $argument).'"';
}

private function replacePlaceholders(string $commandline, array $env)
{
$pattern = '\\' === DIRECTORY_SEPARATOR ? '!%s!' : '"$%s"';

return preg_replace_callback('/\{\{ ?([_a-zA-Z0-9]++) ?\}\}/', function ($m) use ($pattern, $commandline, $env) {
if (!isset($env[$m[1]]) || false === $env[$m[1]]) {
foreach ($env as $k => $v) {
if (false === $v) {
unset($env[$k]);
}
}
if (!$env) {
throw new InvalidArgumentException(sprintf('Invalid command line "%s": no values provided for any placeholders.', $commandline));
}
$env = implode('", "', array_keys($env));

throw new InvalidArgumentException(sprintf('Invalid command line "%s": no value provided for placeholder "%s", did you mean "%s"?', $commandline, $m[1], $env));
}

return sprintf($pattern, $m[1]);
}, $commandline);
}

private function getDefaultEnv()
{
$env = array();
Expand Down
28 changes: 0 additions & 28 deletions src/Symfony/Component/Process/Tests/ProcessTest.php
Expand Up @@ -1474,34 +1474,6 @@ public function provideEscapeArgument()
yield array('éÉèÈàÀöä');
}

public function testPreparedCommand()
{
$p = new Process(self::$phpBin.' -r \'print_r($argv);\' {{ abc }}DEF');
$p->run(null, array('abc' => 'A" B "C'));

$this->assertContains('A" B "CDEF', $p->getOutput());
}

/**
* @expectedException \Symfony\Component\Process\Exception\InvalidArgumentException
* @expectedExceptionMessage Invalid command line "echo {{ abc }}": no value provided for placeholder "abc", did you mean "bcd"?
*/
public function testPreparedCommandWithMissingValue()
{
$p = new Process('echo {{ abc }}');
$p->run(null, array('bcd' => 'BCD'));
}

/**
* @expectedException \Symfony\Component\Process\Exception\InvalidArgumentException
* @expectedExceptionMessage Invalid command line "echo {{ abc }}": no values provided for any placeholders.
*/
public function testPreparedCommandWithNoValues()
{
$p = new Process('echo {{ abc }}');
$p->run();
}

public function testEnvArgument()
{
$env = array('FOO' => 'Foo', 'BAR' => 'Bar');
Expand Down

0 comments on commit d65c43b

Please sign in to comment.