Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 4080ad8

Browse filesBrowse files
[Console] fix parsing escaped chars in StringInput
1 parent 99b4885 commit 4080ad8
Copy full SHA for 4080ad8

File tree

2 files changed

+20
-4
lines changed
Filter options

2 files changed

+20
-4
lines changed

‎src/Symfony/Component/Console/Input/StringInput.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Console/Input/StringInput.php
+19-4Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
*/
2525
class StringInput extends ArgvInput
2626
{
27-
public const REGEX_STRING = '([^\s]+?)(?:\s|(?<!\\\\)"|(?<!\\\\)\'|$)';
27+
public const REGEX_STRING = '([^\s\\\\]+?)';
2828
public const REGEX_QUOTED_STRING = '(?:"([^"\\\\]*(?:\\\\.[^"\\\\]*)*)"|\'([^\'\\\\]*(?:\\\\.[^\'\\\\]*)*)\')';
2929

3030
/**
@@ -47,14 +47,25 @@ private function tokenize(string $input): array
4747
$tokens = [];
4848
$length = \strlen($input);
4949
$cursor = 0;
50+
$token = null;
5051
while ($cursor < $length) {
52+
if ('\\' === $input[$cursor]) {
53+
$token .= $input[++$cursor] ?? '';
54+
++$cursor;
55+
continue;
56+
}
57+
5158
if (preg_match('/\s+/A', $input, $match, 0, $cursor)) {
59+
if (null !== $token) {
60+
$tokens[] = $token;
61+
$token = null;
62+
}
5263
} elseif (preg_match('/([^="\'\s]+?)(=?)('.self::REGEX_QUOTED_STRING.'+)/A', $input, $match, 0, $cursor)) {
53-
$tokens[] = $match[1].$match[2].stripcslashes(str_replace(['"\'', '\'"', '\'\'', '""'], '', substr($match[3], 1, -1)));
64+
$token .= $match[1].$match[2].stripcslashes(str_replace(['"\'', '\'"', '\'\'', '""'], '', substr($match[3], 1, -1)));
5465
} elseif (preg_match('/'.self::REGEX_QUOTED_STRING.'/A', $input, $match, 0, $cursor)) {
55-
$tokens[] = stripcslashes(substr($match[0], 1, -1));
66+
$token .= stripcslashes(substr($match[0], 1, -1));
5667
} elseif (preg_match('/'.self::REGEX_STRING.'/A', $input, $match, 0, $cursor)) {
57-
$tokens[] = stripcslashes($match[1]);
68+
$token .= stripcslashes($match[1]);
5869
} else {
5970
// should never happen
6071
throw new InvalidArgumentException(sprintf('Unable to parse input near "... %s ...".', substr($input, $cursor, 10)));
@@ -63,6 +74,10 @@ private function tokenize(string $input): array
6374
$cursor += \strlen($match[0]);
6475
}
6576

77+
if (null !== $token) {
78+
$tokens[] = $token;
79+
}
80+
6681
return $tokens;
6782
}
6883
}

‎src/Symfony/Component/Console/Tests/Input/StringInputTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Console/Tests/Input/StringInputTest.php
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ public function getTokenizeData()
7171
["--long-option='foo bar''another'", ['--long-option=foo baranother'], '->tokenize() parses long options with a value'],
7272
["--long-option='foo bar'\"another\"", ['--long-option=foo baranother'], '->tokenize() parses long options with a value'],
7373
['foo -a -ffoo --long bar', ['foo', '-a', '-ffoo', '--long', 'bar'], '->tokenize() parses when several arguments and options'],
74+
["--arg='Jenny'\''s'", ["--arg=Jenny's"], '->tokenize() parses quoted quotes'],
7475
];
7576
}
7677

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.