From 0439d792c46efa328d67e098d688435bca1e2700 Mon Sep 17 00:00:00 2001 From: Pieter Noordhuis Date: Wed, 4 Aug 2010 15:29:28 +0200 Subject: [PATCH 1/1] Add tests for quotation in an interactive redis-cli session Patched redis-cli to abort on unexpected quotation. This caused redis-cli to get into an infinite, memory-consuming loop. --- src/redis-cli.c | 21 ++++++++++++++++++--- tests/integration/redis-cli.tcl | 19 +++++++++++++++++++ 2 files changed, 37 insertions(+), 3 deletions(-) diff --git a/src/redis-cli.c b/src/redis-cli.c index 97a119c8..87ebcb69 100644 --- a/src/redis-cli.c +++ b/src/redis-cli.c @@ -378,7 +378,7 @@ static char **splitArguments(char *line, int *argc) { if (*p) { /* get a token */ int inq=0; /* set to 1 if we are in "quotes" */ - int done = 0; + int done=0; if (current == NULL) current = sdsempty(); while(!done) { @@ -397,7 +397,12 @@ static char **splitArguments(char *line, int *argc) { } current = sdscatlen(current,&c,1); } else if (*p == '"') { - done = 1; + /* closing quote must be followed by a space */ + if (*(p+1) && !isspace(*(p+1))) goto err; + done=1; + } else if (!*p) { + /* unterminated quotes */ + goto err; } else { current = sdscatlen(current,p,1); } @@ -429,6 +434,13 @@ static char **splitArguments(char *line, int *argc) { return vector; } } + +err: + while(*argc--) + sdsfree(vector[*argc]); + zfree(vector); + if (current) sdsfree(current); + return NULL; } #define LINE_BUFLEN 4096 @@ -441,7 +453,10 @@ static void repl() { argv = splitArguments(line,&argc); linenoiseHistoryAdd(line); if (config.historyfile) linenoiseHistorySave(config.historyfile); - if (argc > 0) { + if (argv == NULL) { + printf("Invalid argument(s)\n"); + continue; + } else if (argc > 0) { if (strcasecmp(argv[0],"quit") == 0 || strcasecmp(argv[0],"exit") == 0) exit(0); diff --git a/tests/integration/redis-cli.tcl b/tests/integration/redis-cli.tcl index 191c6598..6e106135 100644 --- a/tests/integration/redis-cli.tcl +++ b/tests/integration/redis-cli.tcl @@ -66,4 +66,23 @@ start_server {tags {"cli"}} { r rpush list bar assert_equal "1. \"foo\"\n2. \"bar\"" [run_command $fd "lrange list 0 -1"] } + + test_interactive_cli "Parsing quotes" { + assert_equal "OK" [run_command $fd "set key \"bar\""] + assert_equal "bar" [r get key] + assert_equal "OK" [run_command $fd "set key \" bar \""] + assert_equal " bar " [r get key] + assert_equal "OK" [run_command $fd "set key \"\\\"bar\\\"\""] + assert_equal "\"bar\"" [r get key] + assert_equal "OK" [run_command $fd "set key \"\tbar\t\""] + assert_equal "\tbar\t" [r get key] + + # invalid quotation + assert_equal "Invalid argument(s)" [run_command $fd "get \"\"key"] + assert_equal "Invalid argument(s)" [run_command $fd "get \"key\"x"] + + # quotes after the argument are weird, but should be allowed + assert_equal "OK" [run_command $fd "set key\"\" bar"] + assert_equal "bar" [r get key] + } } -- 2.47.2