From: Yu Watanabe Date: Sat, 31 Aug 2024 02:22:55 +0000 (+0900) Subject: conf-parser: make config_parse_strv() stricter and optionally drop duplicated entries X-Git-Tag: v257-rc1~573^2~7 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c33aacdcb41defd62d48e0100c4bd300dc54db20;p=thirdparty%2Fsystemd.git conf-parser: make config_parse_strv() stricter and optionally drop duplicated entries --- diff --git a/src/shared/conf-parser.c b/src/shared/conf-parser.c index 978a477f6dd..d9ceb4508fb 100644 --- a/src/shared/conf-parser.c +++ b/src/shared/conf-parser.c @@ -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( diff --git a/src/test/test-conf-parser.c b/src/test/test-conf-parser.c index 56430534607..e3afa2f44f8 100644 --- a/src/test/test-conf-parser.c +++ b/src/test/test-conf-parser.c @@ -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) {