summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2022-03-08 10:08:05 +0100
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2022-03-29 16:17:56 +0200
commit25407ad2a785d10b1aadff0c99829ea0cf51082b (patch)
treedc40723e68f5120274359265924c3ea7573bd944
parenttest-os-util: add basic tests for os-release parsing (diff)
downloadsystemd-25407ad2a785d10b1aadff0c99829ea0cf51082b.tar.xz
systemd-25407ad2a785d10b1aadff0c99829ea0cf51082b.zip
basic/env-file: make load-env-file deduplicate entries with the same key
We generally assume parsing like the shell would do it, so the last value should win when there are repeats.
-rw-r--r--src/basic/env-file.c31
-rw-r--r--src/test/test-env-file.c5
-rw-r--r--src/test/test-os-util.c3
3 files changed, 26 insertions, 13 deletions
diff --git a/src/basic/env-file.c b/src/basic/env-file.c
index 3efd77909c..14925e72e1 100644
--- a/src/basic/env-file.c
+++ b/src/basic/env-file.c
@@ -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;
}
diff --git a/src/test/test-env-file.c b/src/test/test-env-file.c
index 886a8e4bc8..461a0f0810 100644
--- a/src/test/test-env-file.c
+++ b/src/test/test-env-file.c
@@ -9,8 +9,13 @@
#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" \
"d= d\\\n" \
diff --git a/src/test/test-os-util.c b/src/test/test-os-util.c
index 5f82748783..d6336c53e9 100644
--- a/src/test/test-os-util.c
+++ b/src/test/test-os-util.c
@@ -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);