bug #10929 [2.3][Process] Add validation on Process input (romainneutron)
This PR was merged into the 2.3 branch.
Discussion
----------
[2.3][Process] Add validation on Process input
| Q | A
| ------------- | ---
| Bug fix? | yes
| New feature? | no
| BC breaks? | no
| Deprecations? | no
| Tests pass? | yes
| Fixed tickets | n/a
| License | MIT
This adds validation on Process input. For the moment, passing a stream would result in a PHP error.
I propose to deprecate values that are not strictly string in 2.6 (see upcoming PR)
Commits
-------
583092b
[Process] Add validation on Process input
This commit is contained in:
commit
c8476ee744
@ -881,6 +881,7 @@ class Process
|
|||||||
* @return self The current Process instance
|
* @return self The current Process instance
|
||||||
*
|
*
|
||||||
* @throws LogicException In case the process is running
|
* @throws LogicException In case the process is running
|
||||||
|
* @throws InvalidArgumentException In case the argument is invalid
|
||||||
*/
|
*/
|
||||||
public function setStdin($stdin)
|
public function setStdin($stdin)
|
||||||
{
|
{
|
||||||
@ -888,7 +889,7 @@ class Process
|
|||||||
throw new LogicException('STDIN can not be set while the process is running.');
|
throw new LogicException('STDIN can not be set while the process is running.');
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->stdin = $stdin;
|
$this->stdin = ProcessUtils::validateInput(sprintf('%s::%s', __CLASS__, __FUNCTION__), $stdin);
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
@ -148,13 +148,15 @@ class ProcessBuilder
|
|||||||
/**
|
/**
|
||||||
* Sets the input of the process.
|
* Sets the input of the process.
|
||||||
*
|
*
|
||||||
* @param string $stdin The input as a string
|
* @param string|null $stdin The input as a string
|
||||||
*
|
*
|
||||||
* @return ProcessBuilder
|
* @return ProcessBuilder
|
||||||
|
*
|
||||||
|
* @throws InvalidArgumentException In case the argument is invalid
|
||||||
*/
|
*/
|
||||||
public function setInput($stdin)
|
public function setInput($stdin)
|
||||||
{
|
{
|
||||||
$this->stdin = $stdin;
|
$this->stdin = ProcessUtils::validateInput(sprintf('%s::%s', __CLASS__, __FUNCTION__), $stdin);
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,8 @@
|
|||||||
|
|
||||||
namespace Symfony\Component\Process;
|
namespace Symfony\Component\Process;
|
||||||
|
|
||||||
|
use Symfony\Component\Process\Exception\InvalidArgumentException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ProcessUtils is a bunch of utility methods.
|
* ProcessUtils is a bunch of utility methods.
|
||||||
*
|
*
|
||||||
@ -72,6 +74,29 @@ class ProcessUtils
|
|||||||
return escapeshellarg($argument);
|
return escapeshellarg($argument);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validates and normalized a Process input
|
||||||
|
*
|
||||||
|
* @param string $caller The name of method call that validates the input
|
||||||
|
* @param mixed $input The input to validate
|
||||||
|
*
|
||||||
|
* @return string The validated input
|
||||||
|
*
|
||||||
|
* @throws InvalidArgumentException In case the input is not valid
|
||||||
|
*/
|
||||||
|
public static function validateInput($caller, $input)
|
||||||
|
{
|
||||||
|
if (null !== $input) {
|
||||||
|
if (is_scalar($input) || (is_object($input) && method_exists($input, '__toString'))) {
|
||||||
|
return (string) $input;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new InvalidArgumentException(sprintf('%s only accepts strings.', $caller));
|
||||||
|
}
|
||||||
|
|
||||||
|
return $input;
|
||||||
|
}
|
||||||
|
|
||||||
private static function isSurroundedBy($arg, $char)
|
private static function isSurroundedBy($arg, $char)
|
||||||
{
|
{
|
||||||
return 2 < strlen($arg) && $char === $arg[0] && $char === $arg[strlen($arg) - 1];
|
return 2 < strlen($arg) && $char === $arg[0] && $char === $arg[strlen($arg) - 1];
|
||||||
|
@ -171,6 +171,47 @@ abstract class AbstractProcessTest extends \PHPUnit_Framework_TestCase
|
|||||||
$process->stop();
|
$process->stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider provideInvalidStdinValues
|
||||||
|
* @expectedException \Symfony\Component\Process\Exception\InvalidArgumentException
|
||||||
|
* @expectedExceptionMessage Symfony\Component\Process\Process::setStdin only accepts strings.
|
||||||
|
*/
|
||||||
|
public function testInvalidStdin($value)
|
||||||
|
{
|
||||||
|
$process = $this->getProcess('php -v');
|
||||||
|
$process->setStdin($value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function provideInvalidStdinValues()
|
||||||
|
{
|
||||||
|
return array(
|
||||||
|
array(array()),
|
||||||
|
array(new NonStringifiable()),
|
||||||
|
array(fopen('php://temporary', 'w')),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider provideStdinValues
|
||||||
|
*/
|
||||||
|
public function testValidStdin($expected, $value)
|
||||||
|
{
|
||||||
|
$process = $this->getProcess('php -v');
|
||||||
|
$process->setStdin($value);
|
||||||
|
$this->assertSame($expected, $process->getStdin());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function provideStdinValues()
|
||||||
|
{
|
||||||
|
return array(
|
||||||
|
array(null, null),
|
||||||
|
array('24.5', 24.5),
|
||||||
|
array('input data', 'input data'),
|
||||||
|
// to maintain BC, supposed to be removed in 3.0
|
||||||
|
array('stringifiable', new Stringifiable()),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
public function chainedCommandsOutputProvider()
|
public function chainedCommandsOutputProvider()
|
||||||
{
|
{
|
||||||
if (defined('PHP_WINDOWS_VERSION_BUILD')) {
|
if (defined('PHP_WINDOWS_VERSION_BUILD')) {
|
||||||
@ -813,3 +854,15 @@ abstract class AbstractProcessTest extends \PHPUnit_Framework_TestCase
|
|||||||
*/
|
*/
|
||||||
abstract protected function getProcess($commandline, $cwd = null, array $env = null, $stdin = null, $timeout = 60, array $options = array());
|
abstract protected function getProcess($commandline, $cwd = null, array $env = null, $stdin = null, $timeout = 60, array $options = array());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class Stringifiable
|
||||||
|
{
|
||||||
|
public function __toString()
|
||||||
|
{
|
||||||
|
return 'stringifiable';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class NonStringifiable
|
||||||
|
{
|
||||||
|
}
|
||||||
|
@ -197,4 +197,14 @@ class ProcessBuilderTest extends \PHPUnit_Framework_TestCase
|
|||||||
$this->assertEquals("'/usr/bin/php'", $process->getCommandLine());
|
$this->assertEquals("'/usr/bin/php'", $process->getCommandLine());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @expectedException \Symfony\Component\Process\Exception\InvalidArgumentException
|
||||||
|
* @expectedExceptionMessage Symfony\Component\Process\ProcessBuilder::setInput only accepts strings.
|
||||||
|
*/
|
||||||
|
public function testInvalidInput()
|
||||||
|
{
|
||||||
|
$builder = ProcessBuilder::create();
|
||||||
|
$builder->setInput(array());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user