diff options
author | Lennart Poettering <lennart@poettering.net> | 2011-01-05 16:06:35 +0100 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2011-01-05 16:06:35 +0100 |
commit | 5f7c426e2a7f72c473f98be9978d243db79d8910 (patch) | |
tree | be5023d062e91526d7394d6624dc0e2d44d6cd5c | |
parent | 38752828029e72e72d80519bb6c67354782ddb72 (diff) |
fragment: properly handle quotes in assignments in EnvironmentFile= files
-rw-r--r-- | TODO | 3 | ||||
-rw-r--r-- | src/load-fragment.c | 18 | ||||
-rw-r--r-- | src/test-env-replace.c | 43 | ||||
-rw-r--r-- | src/util.c | 38 | ||||
-rw-r--r-- | src/util.h | 1 |
5 files changed, 97 insertions, 6 deletions
@@ -13,9 +13,6 @@ * make failing dm detaching in systemd-shutdown less noisy https://bugzilla.redhat.com/show_bug.cgi?id=657497 -* handle quotes in files read by EnvironmentFile= properly - https://bugzilla.redhat.com/show_bug.cgi?id=661291 - * load EnvironmentFile= when starting services, not when reloading configuration https://bugzilla.redhat.com/show_bug.cgi?id=661282 diff --git a/src/load-fragment.c b/src/load-fragment.c index 1b23205a2f..281863264e 100644 --- a/src/load-fragment.c +++ b/src/load-fragment.c @@ -1360,7 +1360,7 @@ static int config_parse_env_file( } while (!feof(f)) { - char l[LINE_MAX], *p; + char l[LINE_MAX], *p, *u; char **t; if (!fgets(l, sizeof(l), f)) { @@ -1381,7 +1381,21 @@ static int config_parse_env_file( if (strchr(COMMENTS, *p)) continue; - t = strv_env_set(*env, p); + if (!(u = normalize_env_assignment(p))) { + log_error("Out of memory"); + r = -ENOMEM; + goto finish; + } + + t = strv_env_set(*env, u); + free(u); + + if (!t) { + log_error("Out of memory"); + r = -ENOMEM; + goto finish; + } + strv_free(*env); *env = t; } diff --git a/src/test-env-replace.c b/src/test-env-replace.c index e8c9dbf736..37dd7ff590 100644 --- a/src/test-env-replace.c +++ b/src/test-env-replace.c @@ -47,7 +47,7 @@ int main(int argc, char *argv[]) { NULL }; - char **i, **r; + char **i, **r, *t; r = replace_env_argv((char**) line, (char**) env); @@ -56,4 +56,45 @@ int main(int argc, char *argv[]) { strv_free(r); + t = normalize_env_assignment("foo=bar"); + printf("%s\n", t); + free(t); + + t = normalize_env_assignment("=bar"); + printf("%s\n", t); + free(t); + + t = normalize_env_assignment("foo="); + printf("%s\n", t); + free(t); + + t = normalize_env_assignment("="); + printf("%s\n", t); + free(t); + + t = normalize_env_assignment(""); + printf("%s\n", t); + free(t); + + t = normalize_env_assignment("a=\"waldo\""); + printf("%s\n", t); + free(t); + + t = normalize_env_assignment("a=\"waldo"); + printf("%s\n", t); + free(t); + + t = normalize_env_assignment("a=waldo\""); + printf("%s\n", t); + free(t); + + t = normalize_env_assignment("a=\'"); + printf("%s\n", t); + free(t); + + t = normalize_env_assignment("a=\'\'"); + printf("%s\n", t); + free(t); + + return 0; } diff --git a/src/util.c b/src/util.c index 08bdec223e..21afdceb8c 100644 --- a/src/util.c +++ b/src/util.c @@ -3326,6 +3326,44 @@ char *unquote(const char *s, const char* quotes) { return strdup(s); } +char *normalize_env_assignment(const char *s) { + char *name, *value, *p, *r; + + p = strchr(s, '='); + + if (!p) { + if (!(r = strdup(s))) + return NULL; + + return strstrip(r); + } + + if (!(name = strndup(s, p - s))) + return NULL; + + if (!(p = strdup(p+1))) { + free(name); + return NULL; + } + + value = unquote(strstrip(p), QUOTES); + free(p); + + if (!value) { + free(p); + free(name); + return NULL; + } + + if (asprintf(&r, "%s=%s", name, value) < 0) + r = NULL; + + free(value); + free(name); + + return r; +} + int wait_for_terminate(pid_t pid, siginfo_t *status) { assert(pid >= 1); assert(status); diff --git a/src/util.h b/src/util.h index 1e4eedfbce..e9ad881e9c 100644 --- a/src/util.h +++ b/src/util.h @@ -355,6 +355,7 @@ char *ellipsize(const char *s, unsigned length, unsigned percent); int touch(const char *path); char *unquote(const char *s, const char *quotes); +char *normalize_env_assignment(const char *s); int wait_for_terminate(pid_t pid, siginfo_t *status); int wait_for_terminate_and_warn(const char *name, pid_t pid); |