chiark / gitweb /
util: fix handling of trailing whitespace in split_quoted()
authorLennart Poettering <lennart@poettering.net>
Wed, 27 Nov 2013 21:37:52 +0000 (22:37 +0100)
committerLennart Poettering <lennart@poettering.net>
Thu, 28 Nov 2013 17:42:18 +0000 (18:42 +0100)
Inspired by a patch by Lukas Nykryn.

src/shared/util.c
src/test/test-strv.c

index d31bd529498365b56e07c7a95be82ab986154d61..0fce2537da1c77ae225668c50bcba4290597af62 100644 (file)
@@ -373,17 +373,21 @@ char *split(const char *c, size_t *l, const char *separator, char **state) {
 /* Split a string into words, but consider strings enclosed in '' and
  * "" as words even if they include spaces. */
 char *split_quoted(const char *c, size_t *l, char **state) {
-        char *current, *e;
+        const char *current, *e;
         bool escaped = false;
 
-        current = *state ? *state : (char*) c;
+        assert(c);
+        assert(l);
+        assert(state);
 
-        if (!*current || *c == 0)
-                return NULL;
+        current = *state ? *state : c;
 
         current += strspn(current, WHITESPACE);
 
-        if (*current == '\'') {
+        if (*current == 0)
+                return NULL;
+
+        else if (*current == '\'') {
                 current ++;
 
                 for (e = current; *e; e++) {
@@ -396,7 +400,8 @@ char *split_quoted(const char *c, size_t *l, char **state) {
                 }
 
                 *l = e-current;
-                *state = *e == 0 ? e : e+1;
+                *state = (char*) (*e == 0 ? e : e+1);
+
         } else if (*current == '\"') {
                 current ++;
 
@@ -410,7 +415,8 @@ char *split_quoted(const char *c, size_t *l, char **state) {
                 }
 
                 *l = e-current;
-                *state = *e == 0 ? e : e+1;
+                *state = (char*) (*e == 0 ? e : e+1);
+
         } else {
                 for (e = current; *e; e++) {
                         if (escaped)
@@ -421,10 +427,10 @@ char *split_quoted(const char *c, size_t *l, char **state) {
                                 break;
                 }
                 *l = e-current;
-                *state = e;
+                *state = (char*) e;
         }
 
-        return (char*) current;
+        return current;
 }
 
 int get_parent_of_pid(pid_t pid, pid_t *_ppid) {
index e46885902bad6519f112d6173700b122b27c8fa0..068e4210979d50e828b34bdeb25908f619e528c8 100644 (file)
@@ -143,6 +143,7 @@ static void test_strv_quote_unquote(const char* const *split, const char *quoted
         char **t;
 
         p = strv_join_quoted((char **)split);
+        assert_se(p);
         printf("-%s- --- -%s-\n", p, quoted); /* fprintf deals with NULL, puts does not */
         assert_se(p);
         assert_se(streq(p, quoted));
@@ -156,6 +157,20 @@ static void test_strv_quote_unquote(const char* const *split, const char *quoted
         }
 }
 
+static void test_strv_quote_unquote2(const char *quoted, const char ** list) {
+        _cleanup_strv_free_ char **s;
+        unsigned i = 0;
+        char **t;
+
+        s = strv_split_quoted(quoted);
+        assert_se(s);
+
+        STRV_FOREACH(t, s)
+                assert_se(streq(list[i++], *t));
+
+        assert_se(list[i] == NULL);
+}
+
 static void test_strv_split(void) {
         char **s;
         unsigned i = 0;
@@ -405,6 +420,18 @@ int main(int argc, char *argv[]) {
         test_strv_quote_unquote(input_table_quotes, QUOTES_STRING);
         test_strv_quote_unquote(input_table_spaces, SPACES_STRING);
 
+        test_strv_quote_unquote2("    foo=bar     \"waldo\"    zzz    ", (const char*[]) { "foo=bar", "waldo", "zzz", NULL });
+        test_strv_quote_unquote2("", (const char*[]) { NULL });
+        test_strv_quote_unquote2(" ", (const char*[]) { NULL });
+        test_strv_quote_unquote2("   ", (const char*[]) { NULL });
+        test_strv_quote_unquote2("   x", (const char*[]) { "x", NULL });
+        test_strv_quote_unquote2("x   ", (const char*[]) { "x", NULL });
+        test_strv_quote_unquote2("  x   ", (const char*[]) { "x", NULL });
+        test_strv_quote_unquote2("  \"x\"   ", (const char*[]) { "x", NULL });
+        test_strv_quote_unquote2("  \'x\'   ", (const char*[]) { "x", NULL });
+        test_strv_quote_unquote2("  \'x\"\'   ", (const char*[]) { "x\"", NULL });
+        test_strv_quote_unquote2("  \"x\'\"   ", (const char*[]) { "x\'", NULL });
+
         test_strv_split();
         test_strv_split_newlines();
         test_strv_split_nulstr();