diff options
author | Lennart Poettering <lennart@poettering.net> | 2010-07-07 20:57:47 +0200 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2010-07-07 20:57:47 +0200 |
commit | 0bab36f250cc79776954fd6066c1e2a33f64c016 (patch) | |
tree | 32856bf052aa86a5e992a120ed74a57ff86d50e7 /src | |
parent | f3d4cc01488e4b7acf05da02b487f93ae9744337 (diff) |
util: properly handle escaped quotes in words in split_quoted()
Diffstat (limited to 'src')
-rw-r--r-- | src/util.c | 48 |
1 files changed, 34 insertions, 14 deletions
diff --git a/src/util.c b/src/util.c index 78eb728121..58b96aec68 100644 --- a/src/util.c +++ b/src/util.c @@ -360,7 +360,8 @@ 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; + char *current, *e; + bool escaped = false; current = *state ? *state : (char*) c; @@ -371,26 +372,45 @@ char *split_quoted(const char *c, size_t *l, char **state) { if (*current == '\'') { current ++; - *l = strcspn(current, "'"); - *state = current+*l; - if (**state == '\'') - (*state)++; + for (e = current; *e; e++) { + if (escaped) + escaped = false; + else if (*e == '\\') + escaped = true; + else if (*e == '\'') + break; + } + + *l = e-current; + *state = *e == 0 ? e : e+1; } else if (*current == '\"') { current ++; - *l = strcspn(current, "\""); - *state = current+*l; - if (**state == '\"') - (*state)++; + for (e = current; *e; e++) { + if (escaped) + escaped = false; + else if (*e == '\\') + escaped = true; + else if (*e == '\"') + break; + } + + *l = e-current; + *state = *e == 0 ? e : e+1; } else { - *l = strcspn(current, WHITESPACE); - *state = current+*l; + for (e = current; *e; e++) { + if (escaped) + escaped = false; + else if (*e == '\\') + escaped = true; + else if (strchr(WHITESPACE, *e)) + break; + } + *l = e-current; + *state = e; } - /* FIXME: Cannot deal with strings that have spaces AND ticks - * in them */ - return (char*) current; } |