From: Lennart Poettering Date: Wed, 11 Nov 2015 21:53:05 +0000 (+0100) Subject: core: fix dependency parsing X-Git-Tag: v228~50^2~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c89f52ac6938374972253d8752ed65f3af0b3ef4;p=thirdparty%2Fsystemd.git core: fix dependency parsing 3d793d29059a7ddf5282efa6b32b953c183d7a4d broke parsing of unit file names that include backslashes, as extract_first_word() strips those. Fix this, by introducing a new EXTRACT_RETAIN_ESCAPE flag which disables looking at any flags, thus being compatible with the classic FOREACH_WORD() behaviour. --- diff --git a/src/basic/extract-word.c b/src/basic/extract-word.c index ff6d211ef4c..fd495692fae 100644 --- a/src/basic/extract-word.c +++ b/src/basic/extract-word.c @@ -128,7 +128,7 @@ int extract_first_word(const char **p, char **ret, const char *separators, Extra } else if (c == quote) { /* found the end quote */ quote = 0; break; - } else if (c == '\\') { + } else if (c == '\\' && !(flags & EXTRACT_RETAIN_ESCAPE)) { backslash = true; break; } else { @@ -146,7 +146,7 @@ int extract_first_word(const char **p, char **ret, const char *separators, Extra else if ((c == '\'' || c == '"') && (flags & EXTRACT_QUOTES)) { quote = c; break; - } else if (c == '\\') { + } else if (c == '\\' && !(flags & EXTRACT_RETAIN_ESCAPE)) { backslash = true; break; } else if (strchr(separators, c)) { diff --git a/src/basic/extract-word.h b/src/basic/extract-word.h index ddc1c4f4636..9606ab64b31 100644 --- a/src/basic/extract-word.h +++ b/src/basic/extract-word.h @@ -24,11 +24,12 @@ #include "macro.h" typedef enum ExtractFlags { - EXTRACT_RELAX = 1, - EXTRACT_CUNESCAPE = 2, - EXTRACT_CUNESCAPE_RELAX = 4, - EXTRACT_QUOTES = 8, + EXTRACT_RELAX = 1, + EXTRACT_CUNESCAPE = 2, + EXTRACT_CUNESCAPE_RELAX = 4, + EXTRACT_QUOTES = 8, EXTRACT_DONT_COALESCE_SEPARATORS = 16, + EXTRACT_RETAIN_ESCAPE = 32, } ExtractFlags; int extract_first_word(const char **p, char **ret, const char *separators, ExtractFlags flags); diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c index 79cabd26e7a..93eeeabe666 100644 --- a/src/core/load-fragment.c +++ b/src/core/load-fragment.c @@ -122,7 +122,7 @@ int config_parse_unit_deps(const char *unit, _cleanup_free_ char *word = NULL, *k = NULL; int r; - r = extract_first_word(&p, &word, NULL, 0); + r = extract_first_word(&p, &word, NULL, EXTRACT_RETAIN_ESCAPE); if (r == 0) break; if (r == -ENOMEM) diff --git a/src/test/test-extract-word.c b/src/test/test-extract-word.c index 09698c07c7a..65d3a0a96e8 100644 --- a/src/test/test-extract-word.c +++ b/src/test/test-extract-word.c @@ -325,6 +325,18 @@ static void test_extract_first_word(void) { assert_se(extract_first_word(&p, &t, ":", EXTRACT_DONT_COALESCE_SEPARATORS) == 0); assert_se(!t); assert_se(!p); + + p = "foo\\xbar"; + assert_se(extract_first_word(&p, &t, NULL, 0) > 0); + assert_se(streq(t, "fooxbar")); + free(t); + assert_se(p == NULL); + + p = "foo\\xbar"; + assert_se(extract_first_word(&p, &t, NULL, EXTRACT_RETAIN_ESCAPE) > 0); + assert_se(streq(t, "foo\\xbar")); + free(t); + assert_se(p == NULL); } static void test_extract_first_word_and_warn(void) {