Skip to content

Commit

Permalink
Merge branch '5.4' into 6.0
Browse files Browse the repository at this point in the history
* 5.4:
  [DependencyInjection] Fix tests
  Remove composer/package-versions-deprecated from allowed plugins
  [RateLimiter] Resolve crash on near-round timestamps
  [Console] fix parsing escaped chars in StringInput
  • Loading branch information
derrabus committed Jan 24, 2022
2 parents 3a3ab72 + 209db6b commit aa05995
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 4 deletions.
23 changes: 19 additions & 4 deletions Input/StringInput.php
Expand Up @@ -24,7 +24,7 @@
*/
class StringInput extends ArgvInput
{
public const REGEX_STRING = '([^\s]+?)(?:\s|(?<!\\\\)"|(?<!\\\\)\'|$)';
public const REGEX_STRING = '([^\s\\\\]+?)';
public const REGEX_QUOTED_STRING = '(?:"([^"\\\\]*(?:\\\\.[^"\\\\]*)*)"|\'([^\'\\\\]*(?:\\\\.[^\'\\\\]*)*)\')';

/**
Expand All @@ -47,14 +47,25 @@ private function tokenize(string $input): array
$tokens = [];
$length = \strlen($input);
$cursor = 0;
$token = null;
while ($cursor < $length) {
if ('\\' === $input[$cursor]) {
$token .= $input[++$cursor] ?? '';
++$cursor;
continue;
}

if (preg_match('/\s+/A', $input, $match, 0, $cursor)) {
if (null !== $token) {
$tokens[] = $token;
$token = null;
}
} elseif (preg_match('/([^="\'\s]+?)(=?)('.self::REGEX_QUOTED_STRING.'+)/A', $input, $match, 0, $cursor)) {
$tokens[] = $match[1].$match[2].stripcslashes(str_replace(['"\'', '\'"', '\'\'', '""'], '', substr($match[3], 1, -1)));
$token .= $match[1].$match[2].stripcslashes(str_replace(['"\'', '\'"', '\'\'', '""'], '', substr($match[3], 1, -1)));
} elseif (preg_match('/'.self::REGEX_QUOTED_STRING.'/A', $input, $match, 0, $cursor)) {
$tokens[] = stripcslashes(substr($match[0], 1, -1));
$token .= stripcslashes(substr($match[0], 1, -1));
} elseif (preg_match('/'.self::REGEX_STRING.'/A', $input, $match, 0, $cursor)) {
$tokens[] = stripcslashes($match[1]);
$token .= $match[1];
} else {
// should never happen
throw new InvalidArgumentException(sprintf('Unable to parse input near "... %s ...".', substr($input, $cursor, 10)));
Expand All @@ -63,6 +74,10 @@ private function tokenize(string $input): array
$cursor += \strlen($match[0]);
}

if (null !== $token) {
$tokens[] = $token;
}

return $tokens;
}
}
1 change: 1 addition & 0 deletions Tests/Input/StringInputTest.php
Expand Up @@ -71,6 +71,7 @@ public function getTokenizeData()
["--long-option='foo bar''another'", ['--long-option=foo baranother'], '->tokenize() parses long options with a value'],
["--long-option='foo bar'\"another\"", ['--long-option=foo baranother'], '->tokenize() parses long options with a value'],
['foo -a -ffoo --long bar', ['foo', '-a', '-ffoo', '--long', 'bar'], '->tokenize() parses when several arguments and options'],
["--arg=\\\"'Jenny'\''s'\\\"", ["--arg=\"Jenny's\""], '->tokenize() parses quoted quotes'],
];
}

Expand Down

0 comments on commit aa05995

Please sign in to comment.