1
1
mirror of https://github.com/systemd/systemd-stable.git synced 2025-01-20 14:03:39 +03:00

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.
This commit is contained in:
Lennart Poettering 2015-11-11 22:53:05 +01:00
parent c129bd5df3
commit c89f52ac69
4 changed files with 20 additions and 7 deletions

View File

@ -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)) {

View File

@ -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);

View File

@ -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)

View File

@ -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) {