summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2011-01-05 16:06:35 +0100
committerLennart Poettering <lennart@poettering.net>2011-01-05 16:06:35 +0100
commit5f7c426e2a7f72c473f98be9978d243db79d8910 (patch)
treebe5023d062e91526d7394d6624dc0e2d44d6cd5c
parent38752828029e72e72d80519bb6c67354782ddb72 (diff)
fragment: properly handle quotes in assignments in EnvironmentFile= files
-rw-r--r--TODO3
-rw-r--r--src/load-fragment.c18
-rw-r--r--src/test-env-replace.c43
-rw-r--r--src/util.c38
-rw-r--r--src/util.h1
5 files changed, 97 insertions, 6 deletions
diff --git a/TODO b/TODO
index c580bbb3d1..5bca513d27 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 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);