X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Fbasic%2Fstrv.c;h=baaa72e674dc98b3ca3126efc1e385019ef361d0;hp=2e2dc3e4436e19d047babe1d66752767c60b156b;hb=c60d32aa37fc0b10451b0d392d90b3b96eb88ebc;hpb=479020f14217990e24e588bf26d9826b18b64d8c diff --git a/src/basic/strv.c b/src/basic/strv.c index 2e2dc3e44..baaa72e67 100644 --- a/src/basic/strv.c +++ b/src/basic/strv.c @@ -648,6 +648,17 @@ char **strv_remove(char **l, const char *s) { } char **strv_parse_nulstr(const char *s, size_t l) { + /* l is the length of the input data, which will be split at NULs into + * elements of the resulting strv. Hence, the number of items in the resulting strv + * will be equal to one plus the number of NUL bytes in the l bytes starting at s, + * unless s[l-1] is NUL, in which case the final empty string is not stored in + * the resulting strv, and length is equal to the number of NUL bytes. + * + * Note that contrary to a normal nulstr which cannot contain empty strings, because + * the input data is terminated by any two consequent NUL bytes, this parser accepts + * empty strings in s. + */ + const char *p; unsigned c = 0, i = 0; char **v; @@ -711,6 +722,13 @@ char **strv_split_nulstr(const char *s) { #if 0 /// UNNEEDED by elogind int strv_make_nulstr(char **l, char **p, size_t *q) { + /* 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, + * and can also be parsed by strv_parse_nulstr as long as the length + * is provided separately. + */ + size_t n_allocated = 0, n = 0; _cleanup_free_ char *m = NULL; char **i; @@ -723,7 +741,7 @@ int strv_make_nulstr(char **l, char **p, size_t *q) { z = strlen(*i); - if (!GREEDY_REALLOC(m, n_allocated, n + z + 1)) + if (!GREEDY_REALLOC(m, n_allocated, n + z + 2)) return -ENOMEM; memcpy(m + n, *i, z + 1); @@ -734,11 +752,14 @@ int strv_make_nulstr(char **l, char **p, size_t *q) { m = new0(char, 1); if (!m) return -ENOMEM; - n = 0; - } + n = 1; + } else + /* make sure there is a second extra NUL at the end of resulting nulstr */ + m[n] = '\0'; + assert(n > 0); *p = m; - *q = n; + *q = n - 1; m = NULL; @@ -888,7 +909,7 @@ int strv_extend_n(char ***l, const char *value, size_t n) { if (n == 0) return 0; - /* Adds the value value n times to l */ + /* Adds the value n times to l */ k = strv_length(*l);