From c89f52ac6938374972253d8752ed65f3af0b3ef4 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 11 Nov 2015 22:53:05 +0100 Subject: [PATCH] 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. --- src/basic/extract-word.c | 4 ++-- src/basic/extract-word.h | 9 +++++---- src/core/load-fragment.c | 2 +- src/test/test-extract-word.c | 12 ++++++++++++ 4 files changed, 20 insertions(+), 7 deletions(-) diff --git a/src/basic/extract-word.c b/src/basic/extract-word.c index ff6d211..fd49569 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 ddc1c4f..9606ab6 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 79cabd2..93eeeab 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 09698c0..65d3a0a 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) { -- 2.7.4