Fix escapeShellArgument (#3663)
diff --git a/lib/src/io.dart b/lib/src/io.dart
index 6f99b5b..46d910c 100644
--- a/lib/src/io.dart
+++ b/lib/src/io.dart
@@ -1090,5 +1090,5 @@
/// Otherwise, wrap with single quotation, and use '\'' to insert single quote.
String escapeShellArgument(String x) =>
RegExp(r'^[a-zA-Z0-9-_=@.]+$').stringMatch(x) == null
- ? "'${x.replaceAll(r'\', '\\').replaceAll("'", r"'\''")}'"
+ ? "'${x.replaceAll(r'\', r'\\').replaceAll("'", r"'\''")}'"
: x;
diff --git a/test/dependency_services/dependency_services_test.dart b/test/dependency_services/dependency_services_test.dart
index 02a32a0..1451d42 100644
--- a/test/dependency_services/dependency_services_test.dart
+++ b/test/dependency_services/dependency_services_test.dart
@@ -21,7 +21,7 @@
String catFile(String filename) {
final path = p.join(d.sandbox, appPath, filename);
if (File(path).existsSync()) {
- final contents = filterUnstableLines(File(path).readAsLinesSync());
+ final contents = File(path).readAsLinesSync().map(filterUnstableText);
return '''
\$ cat $filename
@@ -82,7 +82,7 @@
Future<Iterable<String>> outputLines(Stream<List<int>> stream) async {
final s = await utf8.decodeStream(stream);
if (s.isEmpty) return [];
- return filterUnstableLines(s.split('\n'));
+ return s.split('\n').map(filterUnstableText);
}
Future<void> _listReportApply(
diff --git a/test/io_test.dart b/test/io_test.dart
index 80bd1be..d94e289 100644
--- a/test/io_test.dart
+++ b/test/io_test.dart
@@ -562,6 +562,13 @@
});
}
});
+
+ test('escapeShellArgument', () {
+ expect(escapeShellArgument(r'abc'), r'abc');
+ expect(escapeShellArgument(r'ab c'), r"'ab c'");
+ expect(escapeShellArgument(r'ab\c'), r"'ab\\c'");
+ expect(escapeShellArgument(r"ab\'c"), r"'ab\\'\''c'");
+ });
}
/// Like [withTempDir], but canonicalizes the path before passing it to [fn].
diff --git a/test/test_pub.dart b/test/test_pub.dart
index 57dc3a0..5680407 100644
--- a/test/test_pub.dart
+++ b/test/test_pub.dart
@@ -865,19 +865,17 @@
/// A [StreamMatcher] that matches multiple lines of output.
StreamMatcher emitsLines(String output) => emitsInOrder(output.split('\n'));
-/// Removes output from pub known to be unstable.
-Iterable<String> filterUnstableLines(List<String> input) {
- return input
- // Any paths in output should be relative to the sandbox and with forward
- // slashes to be stable across platforms.
- .map((line) {
- line = line.replaceAll(d.sandbox, r'$SANDBOX').replaceAll(r'\', '/');
- var port = _globalServer?.port;
- if (port != null) {
- line = line.replaceAll(port.toString(), '\$PORT');
- }
- return line;
- });
+/// Removes output from pub known to be unstable across runs or platforms.
+String filterUnstableText(String input) {
+ // Any paths in output should be relative to the sandbox and with forward
+ // slashes to be stable across platforms.
+ input = input.replaceAll(d.sandbox, r'$SANDBOX');
+ input = input.replaceAllMapped(RegExp(r'\\(\S)'), (match) => '/${match[1]}');
+ var port = _globalServer?.port;
+ if (port != null) {
+ input = input.replaceAll(port.toString(), '\$PORT');
+ }
+ return input;
}
/// Runs `pub outdated [args]` and appends the output to [buffer].
@@ -910,12 +908,13 @@
// .join('\n'));
// }
final pipe = stdin == null ? '' : ' echo ${escapeShellArgument(stdin)} |';
- buffer.writeln(filterUnstableLines([
- '\$$pipe pub ${args.map(escapeShellArgument).join(' ')}',
- ...await process.stdout.rest.toList(),
- ]).join('\n'));
- for (final line in filterUnstableLines(await process.stderr.rest.toList())) {
- buffer.writeln('[STDERR] $line');
+ buffer.writeln(
+ '\$$pipe pub ${args.map(filterUnstableText).map(escapeShellArgument).join(' ')}');
+ for (final line in await process.stdout.rest.toList()) {
+ buffer.writeln(filterUnstableText(line));
+ }
+ for (final line in await process.stderr.rest.toList()) {
+ buffer.writeln('[STDERR] ${filterUnstableText(line)}');
}
if (exitCode != 0) {
buffer.writeln('[EXIT CODE] $exitCode');
diff --git a/test/testdata/goldens/help_test/pub add --help.txt b/test/testdata/goldens/help_test/pub add --help.txt
index 9aa4016..ecdabff 100644
--- a/test/testdata/goldens/help_test/pub add --help.txt
+++ b/test/testdata/goldens/help_test/pub add --help.txt
@@ -30,7 +30,7 @@
* Add a git dependency:
`$topLevelProgram pub add 'foo{"git":"https://github.com/foo/foo"}'`
* Add a git dependency with a path and ref specified:
- `$topLevelProgram pub add /
+ `$topLevelProgram pub add \
'foo{"git":{"url":"../foo.git","ref":"branch","path":"subdir"}}'`
Usage: pub add [options] [dev:]<package>[:descriptor] [[dev:]<package>[:descriptor]