chiark / gitweb /
cgroup: always validate cgroup controller names
[elogind.git] / src / shared / fileio.c
index 617afeace2bf0eb14930e4e60814b4326bc95ff3..48dd44239fa6dc9930072b808eb2e140d3a7ffb9 100644 (file)
@@ -177,14 +177,13 @@ static int parse_env_file_internal(
                 void *userdata) {
 
         _cleanup_free_ char *contents = NULL, *key = NULL;
-        size_t key_alloc = 0, n_key = 0, value_alloc = 0, n_value = 0, last_whitespace = (size_t) -1;
+        size_t key_alloc = 0, n_key = 0, value_alloc = 0, n_value = 0, last_value_whitespace = (size_t) -1, last_key_whitespace = (size_t) -1;
         char *p, *value = NULL;
         int r;
 
         enum {
                 PRE_KEY,
                 KEY,
-                PRE_EQUAL,
                 PRE_VALUE,
                 VALUE,
                 VALUE_ESCAPE,
@@ -213,6 +212,8 @@ static int parse_env_file_internal(
                                 state = COMMENT;
                         else if (!strchr(WHITESPACE, c)) {
                                 state = KEY;
+                                last_key_whitespace = (size_t) -1;
+
                                 if (!greedy_realloc((void**) &key, &key_alloc, n_key+2)) {
                                         r = -ENOMEM;
                                         goto fail;
@@ -226,11 +227,15 @@ static int parse_env_file_internal(
                         if (strchr(newline, c)) {
                                 state = PRE_KEY;
                                 n_key = 0;
-                        } else if (strchr(WHITESPACE, c))
-                                state = PRE_EQUAL;
-                        else if (c == '=')
+                        } else if (c == '=') {
                                 state = PRE_VALUE;
-                        else {
+                                last_value_whitespace = (size_t) -1;
+                        } else {
+                                if (!strchr(WHITESPACE, c))
+                                        last_key_whitespace = (size_t) -1;
+                                else if (last_key_whitespace == (size_t) -1)
+                                         last_key_whitespace = n_key;
+
                                 if (!greedy_realloc((void**) &key, &key_alloc, n_key+2)) {
                                         r = -ENOMEM;
                                         goto fail;
@@ -241,19 +246,6 @@ static int parse_env_file_internal(
 
                         break;
 
-                case PRE_EQUAL:
-                        if (strchr(newline, c)) {
-                                state = PRE_KEY;
-                                n_key = 0;
-                        } else if (c == '=')
-                                state = PRE_VALUE;
-                        else if (!strchr(WHITESPACE, c)) {
-                                n_key = 0;
-                                state = COMMENT;
-                        }
-
-                        break;
-
                 case PRE_VALUE:
                         if (strchr(newline, c)) {
                                 state = PRE_KEY;
@@ -262,6 +254,10 @@ static int parse_env_file_internal(
                                 if (value)
                                         value[n_value] = 0;
 
+                                /* strip trailing whitespace from key */
+                                if (last_key_whitespace != (size_t) -1)
+                                        key[last_key_whitespace] = 0;
+
                                 r = push(key, value, userdata);
                                 if (r < 0)
                                         goto fail;
@@ -269,6 +265,7 @@ static int parse_env_file_internal(
                                 n_key = 0;
                                 value = NULL;
                                 value_alloc = n_value = 0;
+
                         } else if (c == '\'')
                                 state = SINGLE_QUOTE_VALUE;
                         else if (c == '\"')
@@ -291,14 +288,19 @@ static int parse_env_file_internal(
                 case VALUE:
                         if (strchr(newline, c)) {
                                 state = PRE_KEY;
+
                                 key[n_key] = 0;
 
                                 if (value)
                                         value[n_value] = 0;
 
-                                /* Chomp off trailing whitespace */
-                                if (last_whitespace != (size_t) -1)
-                                        value[last_whitespace] = 0;
+                                /* Chomp off trailing whitespace from value */
+                                if (last_value_whitespace != (size_t) -1)
+                                        value[last_value_whitespace] = 0;
+
+                                /* strip trailing whitespace from key */
+                                if (last_key_whitespace != (size_t) -1)
+                                        key[last_key_whitespace] = 0;
 
                                 r = push(key, value, userdata);
                                 if (r < 0)
@@ -307,14 +309,15 @@ static int parse_env_file_internal(
                                 n_key = 0;
                                 value = NULL;
                                 value_alloc = n_value = 0;
+
                         } else if (c == '\\') {
                                 state = VALUE_ESCAPE;
-                                last_whitespace = (size_t) -1;
+                                last_value_whitespace = (size_t) -1;
                         } else {
                                 if (!strchr(WHITESPACE, c))
-                                        last_whitespace = (size_t) -1;
-                                else if (last_whitespace == (size_t) -1)
-                                        last_whitespace = n_value;
+                                        last_value_whitespace = (size_t) -1;
+                                else if (last_value_whitespace == (size_t) -1)
+                                        last_value_whitespace = n_value;
 
                                 if (!greedy_realloc((void**) &value, &value_alloc, n_value+2)) {
                                         r = -ENOMEM;
@@ -424,6 +427,14 @@ static int parse_env_file_internal(
                 if (value)
                         value[n_value] = 0;
 
+                if (state == VALUE)
+                        if (last_value_whitespace != (size_t) -1)
+                                value[last_value_whitespace] = 0;
+
+                /* strip trailing whitespace from key */
+                if (last_key_whitespace != (size_t) -1)
+                        key[last_key_whitespace] = 0;
+
                 r = push(key, value, userdata);
                 if (r < 0)
                         goto fail;
@@ -548,8 +559,8 @@ static void write_env_var(FILE *f, const char *v) {
 
 int write_env_file(const char *fname, char **l) {
         char **i;
-        char _cleanup_free_ *p = NULL;
-        FILE _cleanup_fclose_ *f = NULL;
+        _cleanup_free_ char *p = NULL;
+        _cleanup_fclose_ FILE *f = NULL;
         int r;
 
         r = fopen_temporary(fname, &f, &p);