From f20482cca50d7ab7537be07e97d6a324212ffcd2 Mon Sep 17 00:00:00 2001 From: Vladimir Panteleev Date: Tue, 9 Sep 2014 14:20:35 +0000 Subject: [PATCH 1/3] std.process: Update unittest_burnin to test new functions --- std/process.d | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/std/process.d b/std/process.d index f9725a231..db25ecf71 100644 --- a/std/process.d +++ b/std/process.d @@ -2613,7 +2613,7 @@ unittest // rdmd --main -unittest -version=unittest_burnin process.d auto helper = absolutePath("std_process_unittest_helper"); - assert(shell(helper ~ " hello").split("\0")[1..$] == ["hello"], "Helper malfunction"); + assert(executeShell(helper ~ " hello").output.split("\0")[1..$] == ["hello"], "Helper malfunction"); void test(string[] s, string fn) { @@ -2622,19 +2622,23 @@ unittest e = escapeShellCommand(helper ~ s); { - scope(failure) writefln("shell() failed.\nExpected:\t%s\nEncoded:\t%s", s, [e]); - g = shell(e).split("\0")[1..$]; + scope(failure) writefln("executeShell() failed.\nExpected:\t%s\nEncoded:\t%s", s, [e]); + auto result = executeShell(e); + assert(result.status == 0, "std_process_unittest_helper failed"); + g = result.output.split("\0")[1..$]; } - assert(s == g, format("shell() test failed.\nExpected:\t%s\nGot:\t\t%s\nEncoded:\t%s", s, g, [e])); + assert(s == g, format("executeShell() test failed.\nExpected:\t%s\nGot:\t\t%s\nEncoded:\t%s", s, g, [e])); e = escapeShellCommand(helper ~ s) ~ ">" ~ escapeShellFileName(fn); { - scope(failure) writefln("system() failed.\nExpected:\t%s\nFilename:\t%s\nEncoded:\t%s", s, [fn], [e]); - system(e); + scope(failure) writefln("executeShell() with redirect failed.\nExpected:\t%s\nFilename:\t%s\nEncoded:\t%s", s, [fn], [e]); + auto result = executeShell(e); + assert(result.status == 0, "std_process_unittest_helper failed"); + assert(!result.output.length, "No output expected, got:\n" ~ result.output); g = readText(fn).split("\0")[1..$]; } remove(fn); - assert(s == g, format("system() test failed.\nExpected:\t%s\nGot:\t\t%s\nEncoded:\t%s", s, g, [e])); + assert(s == g, format("executeShell() with redirect test failed.\nExpected:\t%s\nGot:\t\t%s\nEncoded:\t%s", s, g, [e])); } while (true) From e0392714f90894771696f2de43a08458508b3cc8 Mon Sep 17 00:00:00 2001 From: Vladimir Panteleev Date: Tue, 9 Sep 2014 14:21:33 +0000 Subject: [PATCH 2/3] std.process: Test random characters at filename start as well --- std/process.d | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/std/process.d b/std/process.d index db25ecf71..1df4e7c16 100644 --- a/std/process.d +++ b/std/process.d @@ -2674,7 +2674,7 @@ unittest } // generate filename - string fn = "test_"; + string fn; foreach (l; 0..uniform(1, 10)) { dchar c; @@ -2697,6 +2697,7 @@ unittest fn ~= c; } + fn = fn[0..$/2] ~ "_testfile_" ~ fn[$/2..$]; test(args, fn); } From 337d82bb37266e57b30607fcd8fc0a826b74690e Mon Sep 17 00:00:00 2001 From: Vladimir Panteleev Date: Thu, 11 Sep 2014 09:38:36 +0000 Subject: [PATCH 3/3] fix Issue 13446 - Can't use executeShell/escapeShellFileName to redirect to file whose name starts with & Discovered and verified by -version=unittest_burnin --- std/process.d | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/std/process.d b/std/process.d index 1df4e7c16..c4b759ab8 100644 --- a/std/process.d +++ b/std/process.d @@ -2589,7 +2589,19 @@ string escapeShellFileName(in char[] fileName) @trusted pure nothrow // preparation - see below. version (Windows) + { + // If a file starts with &, it can cause cmd.exe to misinterpret + // the file name as the stream redirection syntax: + // command > "&foo.txt" + // gets interpreted as + // command >&foo.txt + // Prepend .\ to disambiguate. + + if (fileName.length && fileName[0] == '&') + return cast(string)(`".\` ~ fileName ~ '"'); + return cast(string)('"' ~ fileName ~ '"'); + } else return escapePosixArgument(fileName); }