diff options
author | Lennart Poettering <lennart@poettering.net> | 2016-07-18 11:12:47 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2016-07-18 11:12:47 +0200 |
commit | b6070695c8f94bf47ffca8557048bdd16a833a12 (patch) | |
tree | 08b806c2ea2ff89f55fdd49837832f11833327cd /src/basic/strv.c | |
parent | d909beef0a97d931de92723746a4e3ae9c7f1194 (diff) | |
parent | b60df13b39c0237f9cb1114076464d2431e6bee5 (diff) |
Merge pull request #3745 from keszybz/fix-make-nulstr-confusion
Fix make nulstr confusion
Diffstat (limited to 'src/basic/strv.c')
-rw-r--r-- | src/basic/strv.c | 29 |
1 files changed, 25 insertions, 4 deletions
diff --git a/src/basic/strv.c b/src/basic/strv.c index db315ac10a..34e464d253 100644 --- a/src/basic/strv.c +++ b/src/basic/strv.c @@ -638,6 +638,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; @@ -700,6 +711,13 @@ char **strv_split_nulstr(const char *s) { } 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; @@ -712,7 +730,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); @@ -723,11 +741,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; |