2015-08-17 17:00:26 -07:00
< ? php
/*
* This file is part of the Symfony package .
*
* ( c ) Fabien Potencier < fabien @ symfony . com >
*
* For the full copyright and license information , please view the LICENSE
* file that was distributed with this source code .
*/
namespace Symfony\Component\Process ;
use Symfony\Component\Process\Exception\InvalidArgumentException ;
/**
* ProcessUtils is a bunch of utility methods .
*
* This class contains static methods only and is not meant to be instantiated .
*
* @ author Martin Hasoň < martin . hason @ gmail . com >
*/
class ProcessUtils
{
/**
* This class should not be instantiated .
*/
private function __construct ()
{
}
/**
* Escapes a string to be used as a shell argument .
*
* @ param string $argument The argument that will be escaped
*
* @ return string The escaped argument
*/
public static function escapeArgument ( $argument )
{
//Fix for PHP bug #43784 escapeshellarg removes % from given string
//Fix for PHP bug #49446 escapeshellarg doesn't work on Windows
//@see https://bugs.php.net/bug.php?id=43784
//@see https://bugs.php.net/bug.php?id=49446
if ( '\\' === DIRECTORY_SEPARATOR ) {
if ( '' === $argument ) {
return escapeshellarg ( $argument );
}
$escapedArgument = '' ;
$quote = false ;
2015-08-27 12:03:05 -07:00
foreach ( preg_split ( '/(")/' , $argument , - 1 , PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE ) as $part ) {
2015-08-17 17:00:26 -07:00
if ( '"' === $part ) {
$escapedArgument .= '\\"' ;
} elseif ( self :: isSurroundedBy ( $part , '%' )) {
// Avoid environment variable expansion
$escapedArgument .= '^%"' . substr ( $part , 1 , - 1 ) . '"^%' ;
} else {
// escape trailing backslash
if ( '\\' === substr ( $part , - 1 )) {
$part .= '\\' ;
}
$quote = true ;
$escapedArgument .= $part ;
}
}
if ( $quote ) {
$escapedArgument = '"' . $escapedArgument . '"' ;
}
return $escapedArgument ;
}
return escapeshellarg ( $argument );
}
/**
* Validates and normalizes 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
*
* Passing an object as an input is deprecated since version 2.5 and will be removed in 3.0 .
*/
public static function validateInput ( $caller , $input )
{
if ( null !== $input ) {
if ( is_resource ( $input )) {
return $input ;
}
if ( is_scalar ( $input )) {
return ( string ) $input ;
}
// deprecated as of Symfony 2.5, to be removed in 3.0
if ( is_object ( $input ) && method_exists ( $input , '__toString' )) {
2015-08-27 12:03:05 -07:00
@ trigger_error ( 'Passing an object as an input is deprecated since version 2.5 and will be removed in 3.0.' , E_USER_DEPRECATED );
2015-08-17 17:00:26 -07:00
return ( string ) $input ;
}
throw new InvalidArgumentException ( sprintf ( '%s only accepts strings or stream resources.' , $caller ));
}
return $input ;
}
private static function isSurroundedBy ( $arg , $char )
{
return 2 < strlen ( $arg ) && $char === $arg [ 0 ] && $char === $arg [ strlen ( $arg ) - 1 ];
}
}