summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2014-12-18 17:51:38 -0500
committerAnthony G. Basile <blueness@gentoo.org>2014-12-20 10:32:25 -0500
commitfcaebcecdb8428295bc9096f8f838304b588b56d (patch)
tree72384d1a1dd3a9147d3358874d61ef16974f76e4
parent39e51a34881c4b02aecf2d98f2e9bdd350dec234 (diff)
Treat a trailing backslash as an error
Commit a2a5291b3f5 changed the parser to reject unfinished quoted strings. Unfortunately it introduced an error where a trailing backslash would case an infinite loop. Of course this must fixed, but the question is what to to instead. Allowing trailing backslashes and treating them as normal characters would be one option, but this seems suboptimal. First, there would be inconsistency between handling of quoting and of backslashes. Second, a trailing backslash is most likely an error, at it seems better to point it out to the user than to try to continue. Updated rules: ExecStart=/bin/echo \\ → OK, prints a backslash ExecStart=/bin/echo \ → error ExecStart=/bin/echo "x → error ExecStart=/bin/echo "x"y → error Signed-off-by: Anthony G. Basile <blueness@gentoo.org>
-rw-r--r--src/shared/util.c8
1 files changed, 7 insertions, 1 deletions
diff --git a/src/shared/util.c b/src/shared/util.c
index 5dd2b5b4b3..bd16abc8db 100644
--- a/src/shared/util.c
+++ b/src/shared/util.c
@@ -348,7 +348,7 @@ int safe_atolli(const char *s, long long int *ret_lli) {
static size_t strcspn_escaped(const char *s, const char *reject) {
bool escaped = false;
- size_t n;
+ int n;
for (n=0; s[n]; n++) {
if (escaped)
@@ -358,6 +358,7 @@ static size_t strcspn_escaped(const char *s, const char *reject) {
else if (strchr(reject, s[n]))
break;
}
+
/* if s ends in \, return index of previous char */
return n - escaped;
}
@@ -393,6 +394,11 @@ const char* split(const char **state, size_t *l, const char *separator, bool quo
*state = current++ + *l + 2;
} else if (quoted) {
*l = strcspn_escaped(current, separator);
+ if (current[*l] && !strchr(separator, current[*l])) {
+ /* unfinished escape */
+ *state = current;
+ return NULL;
+ }
*state = current + *l;
} else {
*l = strcspn(current, separator);