This is an automated email from the ASF dual-hosted git repository. khmarbaise pushed a commit to branch MSHARED-750 in repository https://gitbox.apache.org/repos/asf/maven-shared-utils.git
commit 336594396f2e9be8a572100e30a611f8123a837d Author: Kathryn <[email protected]> AuthorDate: Fri Jul 27 09:40:39 2018 +0100 [MSHARED-750] - Unbalanced quotes in command with escaped double quotation mark --- .../maven/shared/utils/cli/CommandLineUtils.java | 46 +++++++++++++++++++--- .../shared/utils/cli/CommandLineUtilsTest.java | 36 +++++++++++------ 2 files changed, 65 insertions(+), 17 deletions(-) diff --git a/src/main/java/org/apache/maven/shared/utils/cli/CommandLineUtils.java b/src/main/java/org/apache/maven/shared/utils/cli/CommandLineUtils.java index 4beea13..3a745ab 100644 --- a/src/main/java/org/apache/maven/shared/utils/cli/CommandLineUtils.java +++ b/src/main/java/org/apache/maven/shared/utils/cli/CommandLineUtils.java @@ -477,8 +477,9 @@ public abstract class CommandLineUtils final int normal = 0; final int inQuote = 1; final int inDoubleQuote = 2; + boolean inEscape = false; int state = normal; - StringTokenizer tok = new StringTokenizer( toProcess, "\"\' ", true ); + final StringTokenizer tok = new StringTokenizer( toProcess, "\"\' \\", true ); List<String> tokens = new ArrayList<String>(); StringBuilder current = new StringBuilder(); @@ -490,31 +491,65 @@ public abstract class CommandLineUtils case inQuote: if ( "\'".equals( nextTok ) ) { - state = normal; + if ( inEscape ) + { + current.append( nextTok ); + inEscape = false; + } + else + { + state = normal; + } } else { current.append( nextTok ); + inEscape = "\\".equals( nextTok ); } break; case inDoubleQuote: if ( "\"".equals( nextTok ) ) { - state = normal; + if ( inEscape ) + { + current.append( nextTok ); + inEscape = false; + } + else + { + state = normal; + } } else { current.append( nextTok ); + inEscape = "\\".equals( nextTok ); } break; default: if ( "\'".equals( nextTok ) ) { - state = inQuote; + if ( inEscape ) + { + inEscape = false; + current.append( nextTok ); + } + else + { + state = inQuote; + } } else if ( "\"".equals( nextTok ) ) { - state = inDoubleQuote; + if ( inEscape ) + { + inEscape = false; + current.append( nextTok ); + } + else + { + state = inDoubleQuote; + } } else if ( " ".equals( nextTok ) ) { @@ -527,6 +562,7 @@ public abstract class CommandLineUtils else { current.append( nextTok ); + inEscape = "\\".equals( nextTok ); } break; } diff --git a/src/test/java/org/apache/maven/shared/utils/cli/CommandLineUtilsTest.java b/src/test/java/org/apache/maven/shared/utils/cli/CommandLineUtilsTest.java index 4ed35ed..d64fdd8 100644 --- a/src/test/java/org/apache/maven/shared/utils/cli/CommandLineUtilsTest.java +++ b/src/test/java/org/apache/maven/shared/utils/cli/CommandLineUtilsTest.java @@ -22,6 +22,7 @@ package org.apache.maven.shared.utils.cli; import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.fail; import java.util.Arrays; import java.util.HashMap; @@ -99,27 +100,38 @@ public class CommandLineUtilsTest assertCmdLineArgs( new String[] { "foo", " ' ", "bar" }, "foo \" ' \" bar" ); } - @Test - public void givenASingleQuoteMarkInArgument_whenExecutingCode_thenExitCode0Returned() throws Exception { - final Process p = exec("echo \"let's go\""); - assertEquals(0, p.exitValue()); + @Test + public void givenASingleQuoteMarkInArgument_whenTranslatingToCmdLineArgs_thenTheQuotationMarkIsNotEscaped() throws Exception + { + final String command = "echo \"let's go\""; + final String[] expected = new String[]{"echo", "let's go"}; + assertCmdLineArgs(expected, command); } @Test - public void givenADoubleQuoteMarkInArgument_whenExecutingCode_thenExitCode0Returned() throws Exception { - final Process p = exec("echo \"let\"s go\""); + public void givenAnEscapedDoubleQuoteMarkInArgument_whenTranslatingToCmdLineArgs_thenTheQuotationMarkRemainsEscaped() throws Exception + { + final String command = "echo \"let\\\"s go\""; + final String[] expected = new String[]{"echo", "let\\\"s go"}; + assertCmdLineArgs(expected, command); + } - assertEquals(0, p.exitValue()); + @Test + public void givenAnEscapedSingleQuoteMarkInArgument_whenTranslatingToCmdLineArgs_thenTheQuotationMarkRemainsEscaped() throws Exception + { + final String command = "echo \"let\\\'s go\""; + final String[] expected = new String[]{"echo", "let\\\'s go"}; + assertCmdLineArgs(expected, command); } - private Process exec(String cmd) throws CommandLineException, InterruptedException { - Process p = new Commandline(cmd).execute(); - Thread.sleep(1000); - return p; + @Test + public void givenAnEscapedDoubleQuoteMarkInArgument_whenTranslatingToCmdLineArgs_thenNoExceptionIsThrown() throws Exception + { + new Commandline("echo \"let\\\"s go\"").execute(); } - private void assertCmdLineArgs( String[] expected, String cmdLine ) + private void assertCmdLineArgs( final String[] expected, final String cmdLine ) throws Exception { String[] actual = CommandLineUtils.translateCommandline( cmdLine );
