mirror of
https://github.com/morgan9e/systemd
synced 2026-04-15 00:47:10 +09:00
Merge pull request #3745 from keszybz/fix-make-nulstr-confusion
Fix make nulstr confusion
This commit is contained in:
@@ -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;
|
||||
|
||||
|
||||
@@ -139,11 +139,7 @@ static int add_to_keyring(const char *keyname, AskPasswordFlags flags, char **pa
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
/* Truncate trailing NUL */
|
||||
assert(n > 0);
|
||||
assert(p[n-1] == 0);
|
||||
|
||||
serial = add_key("user", keyname, p, n-1, KEY_SPEC_USER_KEYRING);
|
||||
serial = add_key("user", keyname, p, n, KEY_SPEC_USER_KEYRING);
|
||||
memory_erase(p, n);
|
||||
if (serial == -1)
|
||||
return -errno;
|
||||
|
||||
@@ -647,7 +647,9 @@ static void test_strv_extend_n(void) {
|
||||
static void test_strv_make_nulstr_one(char **l) {
|
||||
_cleanup_free_ char *b = NULL, *c = NULL;
|
||||
_cleanup_strv_free_ char **q = NULL;
|
||||
const char *s = NULL;
|
||||
size_t n, m;
|
||||
unsigned i = 0;
|
||||
|
||||
assert_se(strv_make_nulstr(l, &b, &n) >= 0);
|
||||
assert_se(q = strv_parse_nulstr(b, n));
|
||||
@@ -656,6 +658,10 @@ static void test_strv_make_nulstr_one(char **l) {
|
||||
assert_se(strv_make_nulstr(q, &c, &m) >= 0);
|
||||
assert_se(m == n);
|
||||
assert_se(memcmp(b, c, m) == 0);
|
||||
|
||||
NULSTR_FOREACH(s, b)
|
||||
assert_se(streq(s, l[i++]));
|
||||
assert_se(i == strv_length(l));
|
||||
}
|
||||
|
||||
static void test_strv_make_nulstr(void) {
|
||||
|
||||
Reference in New Issue
Block a user