From: Filipe Brandenburger Date: Tue, 9 Jun 2015 04:31:43 +0000 (-0700) Subject: util: Introduce unquote_first_word_and_warn X-Git-Tag: v226.4~1^2~312 X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=commitdiff_plain;h=052cd31ffd9de042f25126992294ebd6db5a67c2;p=elogind.git util: Introduce unquote_first_word_and_warn It will try to unquot_first_word, but if it runs into escaping problems it will retry it adding UNQUOTE_CUNESCAPE_RELAX to the flags. If it succeeds on the second try, it will log a warning about it. If it fails both times, it will log an error. Add test cases to confirm it behaves as expected. --- diff --git a/src/shared/util.c b/src/shared/util.c index 46a48c4d6..727be56f5 100644 --- a/src/shared/util.c +++ b/src/shared/util.c @@ -5320,6 +5320,36 @@ finish: return 1; } +int unquote_first_word_and_warn( + const char **p, + char **ret, + UnquoteFlags flags, + const char *unit, + const char *filename, + unsigned line, + const char *rvalue) { + /* Try to unquote it, if it fails, warn about it and try again but this + * time using UNQUOTE_CUNESCAPE_RELAX to keep the backslashes verbatim + * in invalid escape sequences. */ + const char *save; + int r; + + save = *p; + r = unquote_first_word(p, ret, flags); + if (r < 0 && !(flags&UNQUOTE_CUNESCAPE_RELAX)) { + /* Retry it with UNQUOTE_CUNESCAPE_RELAX. */ + *p = save; + r = unquote_first_word(p, ret, flags|UNQUOTE_CUNESCAPE_RELAX); + if (r < 0) + log_syntax(unit, LOG_ERR, filename, line, EINVAL, + "Unbalanced quoting in command line, ignoring: \"%s\"", rvalue); + else + log_syntax(unit, LOG_WARNING, filename, line, EINVAL, + "Invalid escape sequences in command line: \"%s\"", rvalue); + } + return r; +} + int unquote_many_words(const char **p, UnquoteFlags flags, ...) { va_list ap; char **l; diff --git a/src/shared/util.h b/src/shared/util.h index d465d6908..93fe000a2 100644 --- a/src/shared/util.h +++ b/src/shared/util.h @@ -1008,6 +1008,7 @@ typedef enum UnquoteFlags{ } UnquoteFlags; int unquote_first_word(const char **p, char **ret, UnquoteFlags flags); +int unquote_first_word_and_warn(const char **p, char **ret, UnquoteFlags flags, const char *unit, const char *filename, unsigned line, const char *rvalue); int unquote_many_words(const char **p, UnquoteFlags flags, ...) _sentinel_; int free_and_strdup(char **p, const char *s);