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