teknoraver / rpms / systemd

Forked from rpms/systemd a month ago
Clone

Blame SOURCES/0167-basic-env-file-make-load-env-file-deduplicate-entrie.patch

594167
From f990ee961a75791adfdea2f5efb35017a51a310e Mon Sep 17 00:00:00 2001
594167
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
594167
Date: Tue, 8 Mar 2022 10:08:05 +0100
594167
Subject: [PATCH] basic/env-file: make load-env-file deduplicate entries with
594167
 the same key
594167
594167
We generally assume parsing like the shell would do it, so the last value
594167
should win when there are repeats.
594167
594167
(cherry picked from commit 25407ad2a785d10b1aadff0c99829ea0cf51082b)
594167
594167
Related: #2082131
594167
---
594167
 src/basic/env-file.c     | 31 ++++++++++++++++++++-----------
594167
 src/test/test-env-file.c |  5 +++++
594167
 src/test/test-os-util.c  |  3 +--
594167
 3 files changed, 26 insertions(+), 13 deletions(-)
594167
594167
diff --git a/src/basic/env-file.c b/src/basic/env-file.c
594167
index 599b73bc22..0353f3f2a0 100644
594167
--- a/src/basic/env-file.c
594167
+++ b/src/basic/env-file.c
594167
@@ -415,30 +415,39 @@ static int load_env_file_push_pairs(
594167
                 const char *key, char *value,
594167
                 void *userdata,
594167
                 int *n_pushed) {
594167
-        char ***m = userdata;
594167
+        char ***m = ASSERT_PTR(userdata);
594167
+        bool added = false;
594167
         int r;
594167
 
594167
         r = check_utf8ness_and_warn(filename, line, key, value);
594167
         if (r < 0)
594167
                 return r;
594167
 
594167
+        /* Check if the key is present */
594167
+        for (char **t = *m; t && *t; t += 2)
594167
+                if (streq(t[0], key)) {
594167
+                        if (value)
594167
+                                r = free_and_replace(t[1], value);
594167
+                        else
594167
+                                r = free_and_strdup(t+1, "");
594167
+                        goto finish;
594167
+                }
594167
+
594167
         r = strv_extend(m, key);
594167
         if (r < 0)
594167
                 return -ENOMEM;
594167
 
594167
-        if (!value) {
594167
-                r = strv_extend(m, "");
594167
-                if (r < 0)
594167
-                        return -ENOMEM;
594167
-        } else {
594167
+        if (value)
594167
                 r = strv_push(m, value);
594167
-                if (r < 0)
594167
-                        return r;
594167
-        }
594167
+        else
594167
+                r = strv_extend(m, "");
594167
+        added = true;
594167
+ finish:
594167
+        if (r < 0)
594167
+                return r;
594167
 
594167
-        if (n_pushed)
594167
+        if (n_pushed && added)
594167
                 (*n_pushed)++;
594167
-
594167
         return 0;
594167
 }
594167
 
594167
diff --git a/src/test/test-env-file.c b/src/test/test-env-file.c
594167
index 886a8e4bc8..461a0f0810 100644
594167
--- a/src/test/test-env-file.c
594167
+++ b/src/test/test-env-file.c
594167
@@ -9,7 +9,12 @@
594167
 #include "tests.h"
594167
 #include "tmpfile-util.h"
594167
 
594167
+/* In case of repeating keys, later entries win. */
594167
+
594167
 #define env_file_1                              \
594167
+        "a=a\n"                                 \
594167
+        "a=b\n"                                 \
594167
+        "a=b\n"                                 \
594167
         "a=a\n"                                 \
594167
         "b=b\\\n"                               \
594167
         "c\n"                                   \
594167
diff --git a/src/test/test-os-util.c b/src/test/test-os-util.c
594167
index 5f82748783..d6336c53e9 100644
594167
--- a/src/test/test-os-util.c
594167
+++ b/src/test/test-os-util.c
594167
@@ -67,8 +67,7 @@ TEST(load_os_release_pairs) {
594167
 
594167
         _cleanup_strv_free_ char **pairs = NULL;
594167
         assert_se(load_os_release_pairs(NULL, &pairs) == 0);
594167
-        assert_se(strv_equal(pairs, STRV_MAKE("ID", "ignored", // FIXME
594167
-                                              "ID", "the-id",
594167
+        assert_se(strv_equal(pairs, STRV_MAKE("ID", "the-id",
594167
                                               "NAME", "the-name")));
594167
 
594167
         assert_se(unsetenv("SYSTEMD_OS_RELEASE") == 0);