Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

[2.3][Process] Add validation on Process input #10929

Merged
merged 1 commit into from

3 participants

@romainneutron
Collaborator
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)

@romainneutron
Collaborator

Deprecation is proposed in PR #10930

@stof
Collaborator

The phpdoc documents the type of the argument as string. So passing a steam is not supported.

@romainneutron
Collaborator

That's why I added a check. Passing a stream with the current implementation results in an error

@stof
Collaborator

@romainneutron I would just cast the value as string when it is not null, without adding extra exceptions. People passing an object in it are misusing Symfony anyway, so the PHP error does the work too.
If we start using exceptions to validate string inputs being real strings, it would have to be done on the whole framework, and it is not worth it IMO. Even Hack does not go this way. The static analysis is strict about validating input, but the HHVM runtime let things pass through (well, not sure about the way scalar typehints are handled at runtime though, but other types like shapes are not validated at runtime)

@romainneutron
Collaborator

ok, let's cast scalars, throw exceptions for others type? See http://3v4l.org/6HTo5

@romainneutron romainneutron changed the title from [Process] Add validation on Process input to [2.3][Process] Add validation on Process input
@stof
Collaborator

arf, I forgot resources are castable as string. So yeah, this case need to be validated

@stof
Collaborator

btw, the PHP 4.3.3+ error message is funny in your snippet: Warning: fopen(php://memory): failed to open stream: Success

@romainneutron
Collaborator

PR updated.
I added more tests

@romainneutron romainneutron [Process] Add validation on Process input
583092b
@fabpot
Owner

Thank you @romainneutron.

@fabpot fabpot merged commit 583092b into symfony:2.3
@fabpot fabpot referenced this pull request from a commit
@fabpot fabpot bug #10929 [2.3][Process] Add validation on Process input (romainneut…
…ron)

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
c8476ee
@romainneutron romainneutron deleted the romainneutron:stdin-values branch
@fabpot fabpot referenced this pull request from a commit
@fabpot fabpot feature #10930 [Process] Deprecate using values that are not string f…
…or Process::setStdin and ProcessBuilder::setInput (romainneutron)

This PR was merged into the 2.4-dev branch.

Discussion
----------

[Process] Deprecate using values that are not string for Process::setStdin and ProcessBuilder::setInput

| Q             | A
| ------------- | ---
| Bug fix?      | no
| New feature?  | no
| BC breaks?    | no
| Deprecations? | yes
| Tests pass?   | yes
| Fixed tickets | n/a
| License       | MIT

This deprecates passing a `Process` input any value that is not a strict string. This needs #10929 to be merged.
I don't know if the use of `trigger_error` is correct or should be removed.

Commits
-------

9887b83 [Process] Deprecate using values that are not string for Process::setStdin and ProcessBuilder::setInput
bd68412
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on May 17, 2014
  1. @romainneutron

    [Process] Add validation on Process input

    romainneutron authored
This page is out of date. Refresh to see the latest.
View
5 src/Symfony/Component/Process/Process.php
@@ -880,7 +880,8 @@ public function getStdin()
*
* @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)
{
@@ -888,7 +889,7 @@ public function setStdin($stdin)
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;
}
View
6 src/Symfony/Component/Process/ProcessBuilder.php
@@ -148,13 +148,15 @@ public function setEnv($name, $value)
/**
* 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
+ *
+ * @throws InvalidArgumentException In case the argument is invalid
*/
public function setInput($stdin)
{
- $this->stdin = $stdin;
+ $this->stdin = ProcessUtils::validateInput(sprintf('%s::%s', __CLASS__, __FUNCTION__), $stdin);
return $this;
}
View
25 src/Symfony/Component/Process/ProcessUtils.php
@@ -11,6 +11,8 @@
namespace Symfony\Component\Process;
+use Symfony\Component\Process\Exception\InvalidArgumentException;
+
/**
* ProcessUtils is a bunch of utility methods.
*
@@ -72,6 +74,29 @@ public static function escapeArgument($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)
{
return 2 < strlen($arg) && $char === $arg[0] && $char === $arg[strlen($arg) - 1];
View
53 src/Symfony/Component/Process/Tests/AbstractProcessTest.php
@@ -171,6 +171,47 @@ public function testSetStdinWhileRunningThrowsAnException()
$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()
{
if (defined('PHP_WINDOWS_VERSION_BUILD')) {
@@ -813,3 +854,15 @@ public function methodProvider()
*/
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
+{
+}
View
10 src/Symfony/Component/Process/Tests/ProcessBuilderTest.php
@@ -197,4 +197,14 @@ public function testShouldNotThrowALogicExceptionIfNoPrefix()
$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());
+ }
}
Something went wrong with that request. Please try again.