chiark / gitweb /
fragment: properly handle quotes in assignments in EnvironmentFile= files
authorLennart Poettering <lennart@poettering.net>
Wed, 5 Jan 2011 15:06:35 +0000 (16:06 +0100)
committerLennart Poettering <lennart@poettering.net>
Wed, 5 Jan 2011 15:06:35 +0000 (16:06 +0100)
TODO
src/load-fragment.c
src/test-env-replace.c
src/util.c
src/util.h

diff --git a/TODO b/TODO
index c580bbb..5bca513 100644 (file)
--- 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
 
index 1b23205..2818632 100644 (file)
@@ -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;
         }
index e8c9dbf..37dd7ff 100644 (file)
@@ -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;
 }
index 08bdec2..21afdce 100644 (file)
@@ -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);
index 1e4eedf..e9ad881 100644 (file)
@@ -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);