]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
ordered-set: avoid overflow
authorYu Watanabe <watanabe.yu+github@gmail.com>
Fri, 25 Jul 2025 17:58:01 +0000 (02:58 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Fri, 25 Jul 2025 20:00:02 +0000 (05:00 +0900)
Previously, ordered_set_put_strdupv() and friends returns the number of
pushed entries, but that is potentially larger than INT_MAX (of course,
realistically, OOM is triggered in that case).

No caller uses the number of the new entries. Let's return 1 when at
least one element is added.

Fixes CID#1611523.

src/basic/ordered-set.c
src/test/test-ordered-set.c

index 4d2c43cf363770ea00993e57f2f92f442f9bb863..09fdc3dfceefe89ba8df54f8e8a0c9e4f4cfc1d9 100644 (file)
@@ -61,7 +61,7 @@ int ordered_set_put_strdup_full(OrderedSet **s, const struct hash_ops *hash_ops,
 }
 
 int ordered_set_put_strdupv_full(OrderedSet **s, const struct hash_ops *hash_ops, char **l) {
-        int n = 0, r;
+        int r, ret = 0;
 
         assert(s);
 
@@ -70,14 +70,14 @@ int ordered_set_put_strdupv_full(OrderedSet **s, const struct hash_ops *hash_ops
                 if (r < 0)
                         return r;
 
-                n += r;
+                ret = ret || r > 0;
         }
 
-        return n;
+        return ret;
 }
 
 int ordered_set_put_string_set_full(OrderedSet **s, const struct hash_ops *hash_ops, OrderedSet *l) {
-        int n = 0, r;
+        int r, ret = 0;
         char *p;
 
         assert(s);
@@ -89,10 +89,10 @@ int ordered_set_put_string_set_full(OrderedSet **s, const struct hash_ops *hash_
                 if (r < 0)
                         return r;
 
-                n += r;
+                ret = ret || r > 0;
         }
 
-        return n;
+        return ret;
 }
 
 void ordered_set_print(FILE *f, const char *field, OrderedSet *s) {
index 7125dab2c24d62dac014c7553ae3edb88c508d7b..a5cde0171a310b0f29f16606cc0d784ad8f98a68 100644 (file)
@@ -90,18 +90,19 @@ TEST(set_put_string_set) {
         _cleanup_ordered_set_free_ OrderedSet *m = NULL, *q = NULL;
         _cleanup_free_ char **final = NULL; /* "just free" because the strings are in the set */
 
-        assert_se(ordered_set_put_strdup(&m, "1") == 1);
-        assert_se(ordered_set_put_strdup(&m, "22") == 1);
-        assert_se(ordered_set_put_strdup(&m, "333") == 1);
+        ASSERT_OK_POSITIVE(ordered_set_put_strdup(&m, "1"));
+        ASSERT_OK_POSITIVE(ordered_set_put_strdup(&m, "22"));
+        ASSERT_OK_POSITIVE(ordered_set_put_strdup(&m, "333"));
 
-        assert_se(ordered_set_put_strdup(&q, "11") == 1);
-        assert_se(ordered_set_put_strdup(&q, "22") == 1);
-        assert_se(ordered_set_put_strdup(&q, "33") == 1);
+        ASSERT_OK_POSITIVE(ordered_set_put_strdup(&q, "11"));
+        ASSERT_OK_POSITIVE(ordered_set_put_strdup(&q, "22"));
+        ASSERT_OK_POSITIVE(ordered_set_put_strdup(&q, "33"));
 
-        assert_se(ordered_set_put_string_set(&m, q) == 2);
+        ASSERT_OK_POSITIVE(ordered_set_put_string_set(&m, q));
+        ASSERT_OK_ZERO(ordered_set_put_string_set(&m, q));
 
-        assert_se(final = ordered_set_get_strv(m));
-        assert_se(strv_equal(final, STRV_MAKE("1", "22", "333", "11", "33")));
+        ASSERT_NOT_NULL(final = ordered_set_get_strv(m));
+        ASSERT_TRUE(strv_equal(final, STRV_MAKE("1", "22", "333", "11", "33")));
 
         ordered_set_print(stdout, "BAR=", m);
 }