about summary refs log tree commit diff
path: root/shared/systemd/src/basic/strv.c
diff options
context:
space:
mode:
authorMichael Biebl <biebl@debian.org>2020-04-11 21:28:04 +0200
committerMichael Biebl <biebl@debian.org>2020-04-11 21:28:04 +0200
commit1e5977b62f896e844b548c3007ace9e1dfa7f9ed (patch)
tree7a7416ed410e72b6200f3d860fd315ec11cc106b /shared/systemd/src/basic/strv.c
parentb012fa6e1d808e0736c009799c62d835cbfcc1dd (diff)
New upstream version 1.23.90 upstream/1.23.90
Diffstat (limited to 'shared/systemd/src/basic/strv.c')
-rw-r--r--shared/systemd/src/basic/strv.c123
1 files changed, 65 insertions, 58 deletions
diff --git a/shared/systemd/src/basic/strv.c b/shared/systemd/src/basic/strv.c
index aa467132..be1c8325 100644
--- a/shared/systemd/src/basic/strv.c
+++ b/shared/systemd/src/basic/strv.c
@@ -18,8 +18,8 @@
 #include "string-util.h"
 #include "strv.h"
 
-char *strv_find(char **l, const char *name) {
-        char **i;
+char *strv_find(char * const *l, const char *name) {
+        char * const *i;
 
         assert(name);
 
@@ -30,8 +30,8 @@ char *strv_find(char **l, const char *name) {
         return NULL;
 }
 
-char *strv_find_prefix(char **l, const char *name) {
-        char **i;
+char *strv_find_prefix(char * const *l, const char *name) {
+        char * const *i;
 
         assert(name);
 
@@ -42,8 +42,8 @@ char *strv_find_prefix(char **l, const char *name) {
         return NULL;
 }
 
-char *strv_find_startswith(char **l, const char *name) {
-        char **i, *e;
+char *strv_find_startswith(char * const *l, const char *name) {
+        char * const *i, *e;
 
         assert(name);
 
@@ -59,20 +59,15 @@ char *strv_find_startswith(char **l, const char *name) {
         return NULL;
 }
 
-void strv_clear(char **l) {
+char **strv_free(char **l) {
         char **k;
 
         if (!l)
-                return;
+                return NULL;
 
         for (k = l; *k; k++)
                 free(*k);
 
-        *l = NULL;
-}
-
-char **strv_free(char **l) {
-        strv_clear(l);
         return mfree(l);
 }
 
@@ -183,8 +178,8 @@ char **strv_new_internal(const char *x, ...) {
         return r;
 }
 
-int strv_extend_strv(char ***a, char **b, bool filter_duplicates) {
-        char **s, **t;
+int strv_extend_strv(char ***a, char * const *b, bool filter_duplicates) {
+        char * const *s, **t;
         size_t p, q, i = 0, j;
 
         assert(a);
@@ -195,7 +190,10 @@ int strv_extend_strv(char ***a, char **b, bool filter_duplicates) {
         p = strv_length(*a);
         q = strv_length(b);
 
-        t = reallocarray(*a, p + q + 1, sizeof(char *));
+        if (p >= SIZE_MAX - q)
+                return -ENOMEM;
+
+        t = reallocarray(*a, GREEDY_ALLOC_ROUND_UP(p + q + 1), sizeof(char *));
         if (!t)
                 return -ENOMEM;
 
@@ -228,9 +226,9 @@ rollback:
 }
 
 #if 0 /* NM_IGNORED */
-int strv_extend_strv_concat(char ***a, char **b, const char *suffix) {
+int strv_extend_strv_concat(char ***a, char * const *b, const char *suffix) {
+        char * const *s;
         int r;
-        char **s;
 
         STRV_FOREACH(s, b) {
                 char *v;
@@ -349,9 +347,9 @@ int strv_split_extract(char ***t, const char *s, const char *separators, Extract
 }
 #endif /* NM_IGNORED */
 
-char *strv_join_prefix(char **l, const char *separator, const char *prefix) {
+char *strv_join_prefix(char * const *l, const char *separator, const char *prefix) {
+        char * const *s;
         char *r, *e;
-        char **s;
         size_t n, k, m;
 
         if (!separator)
@@ -389,19 +387,18 @@ char *strv_join_prefix(char **l, const char *separator, const char *prefix) {
 
 int strv_push(char ***l, char *value) {
         char **c;
-        size_t n, m;
+        size_t n;
 
         if (!value)
                 return 0;
 
         n = strv_length(*l);
 
-        /* Increase and check for overflow */
-        m = n + 2;
-        if (m < n)
+        /* Check for overflow */
+        if (n > SIZE_MAX-2)
                 return -ENOMEM;
 
-        c = reallocarray(*l, m, sizeof(char*));
+        c = reallocarray(*l, GREEDY_ALLOC_ROUND_UP(n + 2), sizeof(char*));
         if (!c)
                 return -ENOMEM;
 
@@ -414,19 +411,19 @@ int strv_push(char ***l, char *value) {
 
 int strv_push_pair(char ***l, char *a, char *b) {
         char **c;
-        size_t n, m;
+        size_t n;
 
         if (!a && !b)
                 return 0;
 
         n = strv_length(*l);
 
-        /* increase and check for overflow */
-        m = n + !!a + !!b + 1;
-        if (m < n)
+        /* Check for overflow */
+        if (n > SIZE_MAX-3)
                 return -ENOMEM;
 
-        c = reallocarray(*l, m, sizeof(char*));
+        /* increase and check for overflow */
+        c = reallocarray(*l, GREEDY_ALLOC_ROUND_UP(n + !!a + !!b + 1), sizeof(char*));
         if (!c)
                 return -ENOMEM;
 
@@ -566,8 +563,8 @@ char **strv_uniq(char **l) {
         return l;
 }
 
-bool strv_is_uniq(char **l) {
-        char **i;
+bool strv_is_uniq(char * const *l) {
+        char * const *i;
 
         STRV_FOREACH(i, l)
                 if (strv_find(i+1, *i))
@@ -672,7 +669,7 @@ char **strv_split_nulstr(const char *s) {
 }
 #endif /* NM_IGNORED */
 
-int strv_make_nulstr(char **l, char **p, size_t *q) {
+int strv_make_nulstr(char * const *l, char **ret, size_t *ret_size) {
         /* A valid nulstr with two NULs at the end will be created, but
          * q will be the length without the two trailing NULs. Thus the output
          * string is a valid nulstr and can be iterated over using NULSTR_FOREACH,
@@ -682,10 +679,10 @@ int strv_make_nulstr(char **l, char **p, size_t *q) {
 
         size_t n_allocated = 0, n = 0;
         _cleanup_free_ char *m = NULL;
-        char **i;
+        char * const *i;
 
-        assert(p);
-        assert(q);
+        assert(ret);
+        assert(ret_size);
 
         STRV_FOREACH(i, l) {
                 size_t z;
@@ -709,16 +706,16 @@ int strv_make_nulstr(char **l, char **p, size_t *q) {
                 m[n] = '\0';
 
         assert(n > 0);
-        *p = m;
-        *q = n - 1;
+        *ret = m;
+        *ret_size = n - 1;
 
         m = NULL;
 
         return 0;
 }
 
-bool strv_overlap(char **a, char **b) {
-        char **i;
+bool strv_overlap(char * const *a, char * const *b) {
+        char * const *i;
 
         STRV_FOREACH(i, a)
                 if (strv_contains(b, *i))
@@ -738,23 +735,30 @@ char **strv_sort(char **l) {
 }
 #endif /* NM_IGNORED */
 
-bool strv_equal(char **a, char **b) {
+int strv_compare(char * const *a, char * const *b) {
+        int r;
 
-        if (strv_isempty(a))
-                return strv_isempty(b);
+        if (strv_isempty(a)) {
+                if (strv_isempty(b))
+                        return 0;
+                else
+                        return -1;
+        }
 
         if (strv_isempty(b))
-                return false;
+                return 1;
 
-        for ( ; *a || *b; ++a, ++b)
-                if (!streq_ptr(*a, *b))
-                        return false;
+        for ( ; *a || *b; ++a, ++b) {
+                r = strcmp_ptr(*a, *b);
+                if (r != 0)
+                        return r;
+        }
 
-        return true;
+        return 0;
 }
 
-void strv_print(char **l) {
-        char **s;
+void strv_print(char * const *l) {
+        char * const *s;
 
         STRV_FOREACH(s, l)
                 puts(*s);
@@ -808,12 +812,13 @@ char **strv_shell_escape(char **l, const char *bad) {
         return l;
 }
 
-bool strv_fnmatch(char* const* patterns, const char *s, int flags) {
-        char* const* p;
-
-        STRV_FOREACH(p, patterns)
-                if (fnmatch(*p, s, flags) == 0)
+bool strv_fnmatch_full(char* const* patterns, const char *s, int flags, size_t *matched_pos) {
+        for (size_t i = 0; patterns && patterns[i]; i++)
+                if (fnmatch(patterns[i], s, flags) == 0) {
+                        if (matched_pos)
+                                *matched_pos = i;
                         return true;
+                }
 
         return false;
 }
@@ -856,8 +861,10 @@ int strv_extend_n(char ***l, const char *value, size_t n) {
         /* Adds the value n times to l */
 
         k = strv_length(*l);
+        if (n >= SIZE_MAX - k)
+                return -ENOMEM;
 
-        nl = reallocarray(*l, k + n + 1, sizeof(char *));
+        nl = reallocarray(*l, GREEDY_ALLOC_ROUND_UP(k + n + 1), sizeof(char *));
         if (!nl)
                 return -ENOMEM;
 
@@ -880,9 +887,9 @@ rollback:
         return -ENOMEM;
 }
 
-int fputstrv(FILE *f, char **l, const char *separator, bool *space) {
+int fputstrv(FILE *f, char * const *l, const char *separator, bool *space) {
         bool b = false;
-        char **s;
+        char * const *s;
         int r;
 
         /* Like fputs(), but for strv, and with a less stupid argument order */