Skip to content

Commit

Permalink
ZOOKEEPER-1853: zkCli.sh can't issue a CREATE command containing
Browse files Browse the repository at this point in the history
spaces in the data (Ryan Lamore via rgs)

git-svn-id: https://svn.apache.org/repos/asf/zookeeper/trunk@1713303 13f79535-47bb-0310-9956-ffa450edef68
  • Loading branch information
rgs1 committed Nov 8, 2015
1 parent 8080303 commit df7e637
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 9 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
.classpath
.eclipse/
.idea/
.project
.revision/
.settings/
build/
out/
*.iml
src/c/core.*
src/c/TEST-*.txt
src/c/*.la
Expand Down
3 changes: 3 additions & 0 deletions CHANGES.txt
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,9 @@ BUGFIXES:
ZOOKEEPER-2227: stmk four-letter word fails execution at server while reading
trace mask argument (Chris Nauroth via rgs)

ZOOKEEPER-1853: zkCli.sh can't issue a CREATE command containing spaces in
the data (Ryan Lamore via rgs)

IMPROVEMENTS:
ZOOKEEPER-1660 Documentation for Dynamic Reconfiguration (Reed Wanderman-Milne via shralex)

Expand Down
27 changes: 18 additions & 9 deletions src/java/main/org/apache/zookeeper/ZooKeeperMain.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@
import org.apache.zookeeper.ZooDefs.Ids;
import org.apache.zookeeper.data.Stat;
import java.util.StringTokenizer;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.cli.ParseException;
import org.apache.zookeeper.cli.AddAuthCommand;
import org.apache.zookeeper.cli.CliCommand;
Expand Down Expand Up @@ -145,6 +148,8 @@ static class MyCommandOptions {
private Map<String,String> options = new HashMap<String,String>();
private List<String> cmdArgs = null;
private String command = null;
public static final Pattern ARGS_PATTERN = Pattern.compile("\\s*([^\"\']\\S*|\"[^\"]*\"|'[^']*')\\s*");
public static final Pattern QUOTED_PATTERN = Pattern.compile("^([\'\"])(.*)(\\1)$");

public MyCommandOptions() {
options.put("server", "localhost:2181");
Expand Down Expand Up @@ -216,18 +221,22 @@ public boolean parseOptions(String[] args) {
* @return true if parsing succeeded.
*/
public boolean parseCommand( String cmdstring ) {
StringTokenizer cmdTokens = new StringTokenizer(cmdstring, " ");
String[] args = new String[cmdTokens.countTokens()];
int tokenIndex = 0;
while (cmdTokens.hasMoreTokens()) {
args[tokenIndex] = cmdTokens.nextToken();
tokenIndex++;
Matcher matcher = ARGS_PATTERN.matcher(cmdstring);

List args = new LinkedList();
while (matcher.find()) {
String value = matcher.group(1);
if (QUOTED_PATTERN.matcher(value).matches()) {
// Strip off the surrounding quotes
value = value.substring(1, value.length() - 1);
}
args.add(value);
}
if (args.length == 0){
if (args.isEmpty()){
return false;
}
command = args[0];
cmdArgs = Arrays.asList(args);
command = (String)args.get(0);
cmdArgs = args;
return true;
}
}
Expand Down
55 changes: 55 additions & 0 deletions src/java/test/org/apache/zookeeper/ZooKeeperTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,61 @@ public void testParseWithExtraSpaces() throws Exception {
Assert.assertEquals("/ is not taken as second argument", zkMain.cl.getCmdArgument(1), "/");
}

@Test
public void testParseWithQuotes() throws Exception {
final ZooKeeper zk = createClient();
ZooKeeperMain zkMain = new ZooKeeperMain(zk);
for (String quoteChar : new String[] {"'", "\""}) {
String cmdstring = String.format("create /node %1$squoted data%1$s", quoteChar);
zkMain.cl.parseCommand(cmdstring);
Assert.assertEquals("quotes combine arguments", zkMain.cl.getNumArguments(), 3);
Assert.assertEquals("create is not taken as first argument", zkMain.cl.getCmdArgument(0), "create");
Assert.assertEquals("/node is not taken as second argument", zkMain.cl.getCmdArgument(1), "/node");
Assert.assertEquals("quoted data is not taken as third argument", zkMain.cl.getCmdArgument(2), "quoted data");
}
}

@Test
public void testParseWithMixedQuotes() throws Exception {
final ZooKeeper zk = createClient();
ZooKeeperMain zkMain = new ZooKeeperMain(zk);
for (String[] quoteChars : new String[][] {{"'", "\""}, {"\"", "'"}}) {
String outerQuotes = quoteChars[0];
String innerQuotes = quoteChars[1];
String cmdstring = String.format("create /node %1$s%2$squoted data%2$s%1$s", outerQuotes, innerQuotes);
zkMain.cl.parseCommand(cmdstring);
Assert.assertEquals("quotes combine arguments", zkMain.cl.getNumArguments(), 3);
Assert.assertEquals("create is not taken as first argument", zkMain.cl.getCmdArgument(0), "create");
Assert.assertEquals("/node is not taken as second argument", zkMain.cl.getCmdArgument(1), "/node");
Assert.assertEquals("quoted data is not taken as third argument", zkMain.cl.getCmdArgument(2), innerQuotes + "quoted data" + innerQuotes);
}
}

@Test
public void testParseWithEmptyQuotes() throws Exception {
final ZooKeeper zk = createClient();
ZooKeeperMain zkMain = new ZooKeeperMain(zk);
String cmdstring = "create /node ''";
zkMain.cl.parseCommand(cmdstring);
Assert.assertEquals("empty quotes should produce arguments", zkMain.cl.getNumArguments(), 3);
Assert.assertEquals("create is not taken as first argument", zkMain.cl.getCmdArgument(0), "create");
Assert.assertEquals("/node is not taken as second argument", zkMain.cl.getCmdArgument(1), "/node");
Assert.assertEquals("empty string is not taken as third argument", zkMain.cl.getCmdArgument(2), "");
}

@Test
public void testParseWithMultipleQuotes() throws Exception {
final ZooKeeper zk = createClient();
ZooKeeperMain zkMain = new ZooKeeperMain(zk);
String cmdstring = "create /node '' ''";
zkMain.cl.parseCommand(cmdstring);
Assert.assertEquals("expected 5 arguments", zkMain.cl.getNumArguments(), 4);
Assert.assertEquals("create is not taken as first argument", zkMain.cl.getCmdArgument(0), "create");
Assert.assertEquals("/node is not taken as second argument", zkMain.cl.getCmdArgument(1), "/node");
Assert.assertEquals("empty string is not taken as third argument", zkMain.cl.getCmdArgument(2), "");
Assert.assertEquals("empty string is not taken as fourth argument", zkMain.cl.getCmdArgument(3), "");
}

@Test
public void testInvalidCommand() throws Exception {
final ZooKeeper zk = createClient();
Expand Down

0 comments on commit df7e637

Please sign in to comment.