]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
conf-parser: make config_parse_strv() stricter and optionally drop duplicated entries
authorYu Watanabe <watanabe.yu+github@gmail.com>
Sat, 31 Aug 2024 02:22:55 +0000 (11:22 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Sun, 1 Sep 2024 20:41:55 +0000 (05:41 +0900)
src/shared/conf-parser.c
src/test/test-conf-parser.c

index 978a477f6dd7356445e9bd9725654b1320eae835..d9ceb4508fbb624d463ff2d5f37e657be60e3eb4 100644 (file)
@@ -1266,7 +1266,7 @@ int config_parse_strv(
                 const char *section,
                 unsigned section_line,
                 const char *lvalue,
-                int ltype,
+                int ltype, /* When true, duplicated entries will be filtered. */
                 const char *rvalue,
                 void *data,
                 void *userdata) {
@@ -1283,12 +1283,13 @@ int config_parse_strv(
                 return 0;
         }
 
+        _cleanup_strv_free_ char **strv = NULL;
         for (const char *p = rvalue;;) {
-                char *word = NULL;
+                char *word;
 
                 r = extract_first_word(&p, &word, NULL, EXTRACT_UNQUOTE|EXTRACT_RETAIN_ESCAPE);
                 if (r == 0)
-                        return 0;
+                        break;
                 if (r == -ENOMEM)
                         return log_oom();
                 if (r < 0) {
@@ -1296,10 +1297,16 @@ int config_parse_strv(
                         return 0;
                 }
 
-                r = strv_consume(sv, word);
+                r = strv_consume(&strv, word);
                 if (r < 0)
                         return log_oom();
         }
+
+        r = strv_extend_strv(sv, strv, /* filter_duplicates = */ ltype);
+        if (r < 0)
+                return log_oom();
+
+        return 0;
 }
 
 int config_parse_warn_compat(
index 5643053460708d2e15e23f32afc507c28b1ca6ff..e3afa2f44f87ffcd29cb3d14e90568e3a4153547 100644 (file)
@@ -62,10 +62,10 @@ static void test_config_parse_unsigned_one(const char *rvalue, unsigned expected
         assert_se(expected == v);
 }
 
-static void test_config_parse_strv_one(const char *rvalue, char **expected) {
+static void test_config_parse_strv_one(const char *rvalue, bool filter_duplicates, char **expected) {
         _cleanup_strv_free_ char **strv = NULL;
 
-        assert_se(config_parse_strv("unit", "filename", 1, "section", 1, "lvalue", 0, rvalue, &strv, NULL) >= 0);
+        assert_se(config_parse_strv("unit", "filename", 1, "section", 1, "lvalue", filter_duplicates, rvalue, &strv, NULL) >= 0);
         assert_se(strv_equal(expected, strv));
 }
 
@@ -164,12 +164,19 @@ TEST(config_parse_unsigned) {
 }
 
 TEST(config_parse_strv) {
-        test_config_parse_strv_one("", STRV_MAKE_EMPTY);
-        test_config_parse_strv_one("foo", STRV_MAKE("foo"));
-        test_config_parse_strv_one("foo bar foo", STRV_MAKE("foo", "bar", "foo"));
-        test_config_parse_strv_one("\"foo bar\" foo", STRV_MAKE("foo bar", "foo"));
-        test_config_parse_strv_one("\xc3\x80", STRV_MAKE("\xc3\x80"));
-        test_config_parse_strv_one("\xc3\x7f", STRV_MAKE("\xc3\x7f"));
+        test_config_parse_strv_one("", false, STRV_MAKE_EMPTY);
+        test_config_parse_strv_one("foo", false, STRV_MAKE("foo"));
+        test_config_parse_strv_one("foo bar foo", false, STRV_MAKE("foo", "bar", "foo"));
+        test_config_parse_strv_one("\"foo bar\" foo", false, STRV_MAKE("foo bar", "foo"));
+        test_config_parse_strv_one("\xc3\x80", false, STRV_MAKE("\xc3\x80"));
+        test_config_parse_strv_one("\xc3\x7f", false, STRV_MAKE("\xc3\x7f"));
+
+        test_config_parse_strv_one("", true, STRV_MAKE_EMPTY);
+        test_config_parse_strv_one("foo", true, STRV_MAKE("foo"));
+        test_config_parse_strv_one("foo bar foo", true, STRV_MAKE("foo", "bar"));
+        test_config_parse_strv_one("\"foo bar\" foo", true, STRV_MAKE("foo bar", "foo"));
+        test_config_parse_strv_one("\xc3\x80", true, STRV_MAKE("\xc3\x80"));
+        test_config_parse_strv_one("\xc3\x7f", true, STRV_MAKE("\xc3\x7f"));
 }
 
 TEST(config_parse_mode) {