From: Lennart Poettering Date: Wed, 5 Jan 2011 15:06:35 +0000 (+0100) Subject: fragment: properly handle quotes in assignments in EnvironmentFile= files X-Git-Tag: v16~16 X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=commitdiff_plain;h=5f7c426e2a7f72c473f98be9978d243db79d8910 fragment: properly handle quotes in assignments in EnvironmentFile= files --- diff --git a/TODO b/TODO index c580bbb3d..5bca513d2 100644 --- a/TODO +++ b/TODO @@ -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 1b23205a2..281863264 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 e8c9dbf73..37dd7ff59 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 08bdec223..21afdceb8 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 1e4eedfbc..e9ad881e9 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);