summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2015-11-11 22:53:05 +0100
committerLennart Poettering <lennart@poettering.net>2015-11-11 22:53:05 +0100
commitc89f52ac6938374972253d8752ed65f3af0b3ef4 (patch)
treec700addb5615fe76a52c6bf3a5d9a1ea256a6de4 /src
parentc129bd5df3ca08eb352cf69d01d2f374552624ae (diff)
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.
Diffstat (limited to 'src')
-rw-r--r--src/basic/extract-word.c4
-rw-r--r--src/basic/extract-word.h9
-rw-r--r--src/core/load-fragment.c2
-rw-r--r--src/test/test-extract-word.c12
4 files changed, 20 insertions, 7 deletions
diff --git a/src/basic/extract-word.c b/src/basic/extract-word.c
index ff6d211ef4..fd495692fa 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 ddc1c4f463..9606ab64b3 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 79cabd26e7..93eeeabe66 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 09698c07c7..65d3a0a96e 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) {