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]