diff --git a/blaze-core/src/main/java/com/fizzed/blaze/system/Exec.java b/blaze-core/src/main/java/com/fizzed/blaze/system/Exec.java index d934d8ff..46241ebd 100644 --- a/blaze-core/src/main/java/com/fizzed/blaze/system/Exec.java +++ b/blaze-core/src/main/java/com/fizzed/blaze/system/Exec.java @@ -23,7 +23,8 @@ public Result(Exec action, Integer value) { protected final VerboseLogger log; protected final Map environment; - protected Path command; + // to re-use command for ssh, it needs to be a string as a local Path != remote path + protected String command; protected Path workingDirectory; final protected List arguments; protected StreamableInput pipeInput; @@ -68,19 +69,19 @@ public Exec shell(boolean shell) { public Exec command(Path command) { Objects.requireNonNull(command, "command was null"); - this.command = command; + this.command = command.toString(); return this; } public Exec command(File command) { Objects.requireNonNull(command, "command was null"); - this.command = command.toPath(); + this.command = command.toPath().toString(); return this; } public Exec command(String command) { Objects.requireNonNull(command, "command was null"); - this.command = Paths.get(command); + this.command = command; return this; } diff --git a/blaze-jsync/pom.xml b/blaze-jsync/pom.xml index aed6c0d0..1cd56e54 100644 --- a/blaze-jsync/pom.xml +++ b/blaze-jsync/pom.xml @@ -13,7 +13,7 @@ com.fizzed.blaze.jsync - 1.3.0 + 1.4.0 diff --git a/blaze-jsync/src/main/java/com/fizzed/blaze/jsync/Jsync.java b/blaze-jsync/src/main/java/com/fizzed/blaze/jsync/Jsync.java index cbbb8f76..a1fb18ba 100644 --- a/blaze-jsync/src/main/java/com/fizzed/blaze/jsync/Jsync.java +++ b/blaze-jsync/src/main/java/com/fizzed/blaze/jsync/Jsync.java @@ -315,13 +315,18 @@ public void willEnd(VirtualFileSystem sourceVfs, VirtualPath sourcePath, Virtual } @Override - public void willExcludePath(VirtualPath targetPath) { - log.verbose("Excluding {}", targetPath); + public void willExcludePath(VirtualPath sourcePath) { + log.verbose("Excluding {}", sourcePath); } @Override - public void willIgnorePath(VirtualPath targetPath) { - log.verbose("Ignoring {}", targetPath); + public void willIgnoreSourcePath(VirtualPath sourcePath) { + log.verbose("Ignoring source {}", sourcePath); + } + + @Override + public void willIgnoreTargetPath(VirtualPath targetPath) { + log.verbose("Ignoring target {}", targetPath); } @Override diff --git a/blaze-ssh/src/main/java/com/fizzed/blaze/ssh/impl/JschExec.java b/blaze-ssh/src/main/java/com/fizzed/blaze/ssh/impl/JschExec.java index dfb2c202..f5f8c506 100644 --- a/blaze-ssh/src/main/java/com/fizzed/blaze/ssh/impl/JschExec.java +++ b/blaze-ssh/src/main/java/com/fizzed/blaze/ssh/impl/JschExec.java @@ -156,7 +156,8 @@ public void close() throws IOException { } // passthru the command as-is - c.add(command.toString()); + c.add(command); + // all all the arguments back c.addAll(this.arguments); diff --git a/blaze-ssh/src/main/java/com/fizzed/blaze/ssh/util/SshArguments.java b/blaze-ssh/src/main/java/com/fizzed/blaze/ssh/util/SshArguments.java index 01040fba..96c2d99f 100644 --- a/blaze-ssh/src/main/java/com/fizzed/blaze/ssh/util/SshArguments.java +++ b/blaze-ssh/src/main/java/com/fizzed/blaze/ssh/util/SshArguments.java @@ -7,7 +7,7 @@ public class SshArguments { // Pattern for characters that are safe to leave unquoted. // Alphanumeric, hyphen, underscore, dot, slash, and equals (often used in flags). - static private final Pattern SAFE_CHARS = Pattern.compile("^[a-zA-Z0-9\\-_./=@:,+]+$"); + static private final Pattern SAFE_CHARS = Pattern.compile("^[a-zA-Z0-9\\\\\\-_./=@:,+]+$"); static private boolean isAlreadyQuoted(String arg) { if (arg.length() < 2) return false; diff --git a/blaze-ssh/src/test/java/com/fizzed/blaze/ssh/SshExecTest.java b/blaze-ssh/src/test/java/com/fizzed/blaze/ssh/SshExecTest.java index f4fd2c65..10743266 100644 --- a/blaze-ssh/src/test/java/com/fizzed/blaze/ssh/SshExecTest.java +++ b/blaze-ssh/src/test/java/com/fizzed/blaze/ssh/SshExecTest.java @@ -266,7 +266,77 @@ public void commandRetainsSlashes() throws Exception { assertThat(exitValue, is(0)); } - + + @Test + public void commandRetainsSlashesWindows() throws Exception { + // what happens when a command received over ssh + commandHandler = (SshCommand command) -> { + if (command.line.equals("path\\to\\exec a=1 b=2")) { + command.exit.onExit(0); + } else { + command.exit.onExit(1); + } + }; + + SshSession session = startAndConnect(); + + Integer exitValue + = new JschExec(context, session) + .command("path\\to\\exec") + .arg("a=1") + .args("b=2") + .run(); + + assertThat(exitValue, is(0)); + } + + @Test + public void commandUnsafeCharsSmartQuoted() throws Exception { + // what happens when a command received over ssh + commandHandler = (SshCommand command) -> { + if (command.line.equals("path/to/exec 'hello world' 'my$name.class' \"i know what i am doing\"")) { + command.exit.onExit(0); + } else { + command.exit.onExit(1); + } + }; + + SshSession session = startAndConnect(); + + Integer exitValue + = new JschExec(context, session) + .command("path/to/exec") + .arg("hello world") + .args("my$name.class") + .arg("\"i know what i am doing\"") + .run(); + + assertThat(exitValue, is(0)); + } + + @Test + public void commandWindowsPathSmartQuoted() throws Exception { + // what happens when a command received over ssh + commandHandler = (SshCommand command) -> { + if (command.line.equals("'C:\\Program Files\\Git\\usr\\bin\\cksum.exe' 'hello world' 'my$name.class'")) { + command.exit.onExit(0); + } else { + command.exit.onExit(1); + } + }; + + SshSession session = startAndConnect(); + + Integer exitValue + = new JschExec(context, session) + .command("C:\\Program Files\\Git\\usr\\bin\\cksum.exe") + .arg("hello world") + .args("my$name.class") + .run(); + + assertThat(exitValue, is(0)); + } + @Test public void nullInputAndOutputs() throws Exception { // what happens when a command received over ssh diff --git a/blaze-ssh/src/test/java/com/fizzed/blaze/ssh/util/SshArgumentsTest.java b/blaze-ssh/src/test/java/com/fizzed/blaze/ssh/util/SshArgumentsTest.java index 0ad2374c..d2804cd9 100644 --- a/blaze-ssh/src/test/java/com/fizzed/blaze/ssh/util/SshArgumentsTest.java +++ b/blaze-ssh/src/test/java/com/fizzed/blaze/ssh/util/SshArgumentsTest.java @@ -43,4 +43,18 @@ public void escapeDollarSigns() { assertThat(cmd, is("a '$b.class' c")); } + @Test + public void posixPathChars() { + String cmd = SshArguments.smartEscapedCommandLine(asList("a/b/c", "d"), false); + + assertThat(cmd, is("a/b/c d")); + } + + @Test + public void windowsPathChars() { + String cmd = SshArguments.smartEscapedCommandLine(asList("a\\b\\c", "d"), false); + + assertThat(cmd, is("a\\b\\c d")); + } + } \ No newline at end of file