]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
basic/env-file: make load-env-file deduplicate entries with the same key
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Tue, 8 Mar 2022 09:08:05 +0000 (10:08 +0100)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Tue, 29 Mar 2022 14:17:56 +0000 (16:17 +0200)
We generally assume parsing like the shell would do it, so the last value
should win when there are repeats.

src/basic/env-file.c
src/test/test-env-file.c
src/test/test-os-util.c

index 3efd77909c617f2e445e7180ab54c4aaea5308dd..14925e72e195de50972f54f33c112abcfb0786d5 100644 (file)
@@ -414,30 +414,39 @@ static int load_env_file_push_pairs(
                 const char *key, char *value,
                 void *userdata,
                 int *n_pushed) {
-        char ***m = userdata;
+        char ***m = ASSERT_PTR(userdata);
+        bool added = false;
         int r;
 
         r = check_utf8ness_and_warn(filename, line, key, value);
         if (r < 0)
                 return r;
 
+        /* Check if the key is present */
+        for (char **t = *m; t && *t; t += 2)
+                if (streq(t[0], key)) {
+                        if (value)
+                                r = free_and_replace(t[1], value);
+                        else
+                                r = free_and_strdup(t+1, "");
+                        goto finish;
+                }
+
         r = strv_extend(m, key);
         if (r < 0)
                 return -ENOMEM;
 
-        if (!value) {
-                r = strv_extend(m, "");
-                if (r < 0)
-                        return -ENOMEM;
-        } else {
+        if (value)
                 r = strv_push(m, value);
-                if (r < 0)
-                        return r;
-        }
+        else
+                r = strv_extend(m, "");
+        added = true;
+ finish:
+        if (r < 0)
+                return r;
 
-        if (n_pushed)
+        if (n_pushed && added)
                 (*n_pushed)++;
-
         return 0;
 }
 
index 886a8e4bc85787da95bc27451e67938eea126674..461a0f0810177dcf237850eef9ae874e5bfba26d 100644 (file)
@@ -9,7 +9,12 @@
 #include "tests.h"
 #include "tmpfile-util.h"
 
+/* In case of repeating keys, later entries win. */
+
 #define env_file_1                              \
+        "a=a\n"                                 \
+        "a=b\n"                                 \
+        "a=b\n"                                 \
         "a=a\n"                                 \
         "b=b\\\n"                               \
         "c\n"                                   \
index 5f82748783fa65461ed47789bcde81413e91a3d5..d6336c53e9dfaddc1b238fdce7b6204b51c60786 100644 (file)
@@ -67,8 +67,7 @@ TEST(load_os_release_pairs) {
 
         _cleanup_strv_free_ char **pairs = NULL;
         assert_se(load_os_release_pairs(NULL, &pairs) == 0);
-        assert_se(strv_equal(pairs, STRV_MAKE("ID", "ignored", // FIXME
-                                              "ID", "the-id",
+        assert_se(strv_equal(pairs, STRV_MAKE("ID", "the-id",
                                               "NAME", "the-name")));
 
         assert_se(unsetenv("SYSTEMD_OS_RELEASE") == 0);