Просмотр файла vendor/symfony/process/ProcessUtils.php

Размер файла: 3.54Kb
  1. <?php
  2.  
  3. /*
  4. * This file is part of the Symfony package.
  5. *
  6. * (c) Fabien Potencier <fabien@symfony.com>
  7. *
  8. * For the full copyright and license information, please view the LICENSE
  9. * file that was distributed with this source code.
  10. */
  11.  
  12. namespace Symfony\Component\Process;
  13.  
  14. use Symfony\Component\Process\Exception\InvalidArgumentException;
  15.  
  16. /**
  17. * ProcessUtils is a bunch of utility methods.
  18. *
  19. * This class contains static methods only and is not meant to be instantiated.
  20. *
  21. * @author Martin Hasoň <martin.hason@gmail.com>
  22. */
  23. class ProcessUtils
  24. {
  25. /**
  26. * This class should not be instantiated.
  27. */
  28. private function __construct()
  29. {
  30. }
  31.  
  32. /**
  33. * Escapes a string to be used as a shell argument.
  34. *
  35. * @param string $argument The argument that will be escaped
  36. *
  37. * @return string The escaped argument
  38. */
  39. public static function escapeArgument($argument)
  40. {
  41. //Fix for PHP bug #43784 escapeshellarg removes % from given string
  42. //Fix for PHP bug #49446 escapeshellarg doesn't work on Windows
  43. //@see https://bugs.php.net/bug.php?id=43784
  44. //@see https://bugs.php.net/bug.php?id=49446
  45. if ('\\' === DIRECTORY_SEPARATOR) {
  46. if ('' === $argument) {
  47. return escapeshellarg($argument);
  48. }
  49.  
  50. $escapedArgument = '';
  51. $quote = false;
  52. foreach (preg_split('/(")/', $argument, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE) as $part) {
  53. if ('"' === $part) {
  54. $escapedArgument .= '\\"';
  55. } elseif (self::isSurroundedBy($part, '%')) {
  56. // Avoid environment variable expansion
  57. $escapedArgument .= '^%"'.substr($part, 1, -1).'"^%';
  58. } else {
  59. // escape trailing backslash
  60. if ('\\' === substr($part, -1)) {
  61. $part .= '\\';
  62. }
  63. $quote = true;
  64. $escapedArgument .= $part;
  65. }
  66. }
  67. if ($quote) {
  68. $escapedArgument = '"'.$escapedArgument.'"';
  69. }
  70.  
  71. return $escapedArgument;
  72. }
  73.  
  74. return escapeshellarg($argument);
  75. }
  76.  
  77. /**
  78. * Validates and normalizes a Process input.
  79. *
  80. * @param string $caller The name of method call that validates the input
  81. * @param mixed $input The input to validate
  82. *
  83. * @return mixed The validated input
  84. *
  85. * @throws InvalidArgumentException In case the input is not valid
  86. */
  87. public static function validateInput($caller, $input)
  88. {
  89. if (null !== $input) {
  90. if (is_resource($input)) {
  91. return $input;
  92. }
  93. if (is_string($input)) {
  94. return $input;
  95. }
  96. if (is_scalar($input)) {
  97. return (string) $input;
  98. }
  99. if ($input instanceof Process) {
  100. return $input->getIterator($input::ITER_SKIP_ERR);
  101. }
  102. if ($input instanceof \Iterator) {
  103. return $input;
  104. }
  105. if ($input instanceof \Traversable) {
  106. return new \IteratorIterator($input);
  107. }
  108.  
  109. throw new InvalidArgumentException(sprintf('%s only accepts strings, Traversable objects or stream resources.', $caller));
  110. }
  111.  
  112. return $input;
  113. }
  114.  
  115. private static function isSurroundedBy($arg, $char)
  116. {
  117. return 2 < strlen($arg) && $char === $arg[0] && $char === $arg[strlen($arg) - 1];
  118. }
  119. }