You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by pa...@apache.org on 2015/09/01 20:22:41 UTC

[5/6] incubator-groovy git commit: GROOVY-7566: groovysh: Fix CommandArgumentParser problems with escaping

GROOVY-7566: groovysh: Fix CommandArgumentParser problems with escaping


Project: http://git-wip-us.apache.org/repos/asf/incubator-groovy/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-groovy/commit/01ea7ace
Tree: http://git-wip-us.apache.org/repos/asf/incubator-groovy/tree/01ea7ace
Diff: http://git-wip-us.apache.org/repos/asf/incubator-groovy/diff/01ea7ace

Branch: refs/heads/master
Commit: 01ea7acec2b0c8c6e648e22dfd38c4299e73fae9
Parents: 90b65d8
Author: Thibault Kruse <th...@gmx.de>
Authored: Wed Aug 19 15:44:56 2015 +0200
Committer: pascalschumacher <pa...@gmx.net>
Committed: Tue Sep 1 20:20:52 2015 +0200

----------------------------------------------------------------------
 .../shell/util/CommandArgumentParser.groovy     | 27 +++++++++++++++-----
 .../shell/util/CommandArgumentParserTest.groovy | 12 +++++++--
 2 files changed, 30 insertions(+), 9 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-groovy/blob/01ea7ace/subprojects/groovy-groovysh/src/main/groovy/org/codehaus/groovy/tools/shell/util/CommandArgumentParser.groovy
----------------------------------------------------------------------
diff --git a/subprojects/groovy-groovysh/src/main/groovy/org/codehaus/groovy/tools/shell/util/CommandArgumentParser.groovy b/subprojects/groovy-groovysh/src/main/groovy/org/codehaus/groovy/tools/shell/util/CommandArgumentParser.groovy
index f1cede4..f651647 100644
--- a/subprojects/groovy-groovysh/src/main/groovy/org/codehaus/groovy/tools/shell/util/CommandArgumentParser.groovy
+++ b/subprojects/groovy-groovysh/src/main/groovy/org/codehaus/groovy/tools/shell/util/CommandArgumentParser.groovy
@@ -25,7 +25,7 @@ class CommandArgumentParser {
 
     /**
      * takes a String and tokenizes it according to posix-shell-like rules, meaning
-     * arguments are separated by blanks or hyphens, and hyphens wrap tokens regardless
+     * arguments are separated by non-escaped blanks or hyphens, and hyphens wrap tokens regardless
      * of blanks, other hyphens or escaped hyphens within the wrapping hyphens.
      *
      * Example: "foo bar 123'456' 'abc\'def\\' ''"  has 6 tokens:
@@ -50,12 +50,25 @@ class CommandArgumentParser {
                 break
             }
             String ch = line.charAt(index)
-            // escaped char?
-            if (ch == '\\' && (singleHyphenOpen || doubleHyphenOpen)) {
-                ch = (index == line.length() - 1) ? '\\' : line.charAt(index + 1)
-                index++
-                currentToken += ch
-                continue
+            // escaped char? -> maybe unescape
+            if (ch == '\\') {
+                if (index >= line.length() - 1) {
+                    // end reached
+                    currentToken += ch
+                    continue
+                }
+                if (singleHyphenOpen || doubleHyphenOpen) {
+                    // add escaped, no other parsing action
+                    currentToken += ch
+                    index++
+                    currentToken += line.charAt(index)
+                    continue
+                } else {
+                    // unescape, only add char after, no parsing action
+                    index++
+                    currentToken += line.charAt(index)
+                    continue
+                }
             }
 
             if (ch == '"' && !singleHyphenOpen) {

http://git-wip-us.apache.org/repos/asf/incubator-groovy/blob/01ea7ace/subprojects/groovy-groovysh/src/test/groovy/org/codehaus/groovy/tools/shell/util/CommandArgumentParserTest.groovy
----------------------------------------------------------------------
diff --git a/subprojects/groovy-groovysh/src/test/groovy/org/codehaus/groovy/tools/shell/util/CommandArgumentParserTest.groovy b/subprojects/groovy-groovysh/src/test/groovy/org/codehaus/groovy/tools/shell/util/CommandArgumentParserTest.groovy
index 2ef73b4..ed4f1eb 100644
--- a/subprojects/groovy-groovysh/src/test/groovy/org/codehaus/groovy/tools/shell/util/CommandArgumentParserTest.groovy
+++ b/subprojects/groovy-groovysh/src/test/groovy/org/codehaus/groovy/tools/shell/util/CommandArgumentParserTest.groovy
@@ -28,6 +28,9 @@ class CommandArgumentParserTest extends GroovyTestCase {
         // blanks
         assert ['foo', 'bar'] == CommandArgumentParser.parseLine('  foo bar  ')
 
+        // escaped blanks
+        assert ['foo bar'] == CommandArgumentParser.parseLine('foo\\ bar')
+
         // empties
         assert ['', '', '', ''] == CommandArgumentParser.parseLine('\'\'\'\' \'\'  \'\'')
         assert ['', '', '', ''] == CommandArgumentParser.parseLine('"""" ""  ""')
@@ -36,8 +39,13 @@ class CommandArgumentParserTest extends GroovyTestCase {
         assert ['foo bar', 'baz bam'] == CommandArgumentParser.parseLine(' \'foo bar\' \'baz bam\'')
         assert ['foo bar', 'baz bam'] == CommandArgumentParser.parseLine(' "foo bar" "baz bam"')
 
-        // escaped hyphens and escape signs
-        assert ['foo \\ "\' bar'] == CommandArgumentParser.parseLine('\'foo \\\\ "\\\' bar\'')
+        // escaped hyphens and escape signs within hyphens
+        // intentionally adding list on left hand side because power asserts become confusing with escaping
+        assert [] + ['foo \\\\ "\\\' bar'] == CommandArgumentParser.parseLine('\'foo \\\\ "\\\' bar\'')
+
+        // escaped hyphens and escape signs outside hyphens
+        assert [] + ['foo', '\\', '"', '\'', 'bar'] == CommandArgumentParser.parseLine('foo \\\\ \\" \\\' bar')
+
         // no space between hyphentokens
         assert ['bar', 'foo', 'bam', 'baz'] == CommandArgumentParser.parseLine('bar"foo"\'bam\'\'baz\'')