Introduce free_and_strndup and use it in bus-message.c

v2: fix error in free_and_strndup()

When the orignal and copied message were the same, but shorter than specified
length l, memory read past the end of the buffer would be performed. A test
case is included: a string that had an embedded NUL ("q\0") is used to replace
"q".

v3: Fix one more bug in free_and_strndup and add tests.

v4: Some style fixed based on review, one more use of free_and_replace, and
make the tests more comprehensive.
This commit is contained in:
Zbigniew Jędrzejewski-Szmek
2018-10-02 11:42:45 +02:00
parent 56b560c263
commit 7f546026ab
5 changed files with 103 additions and 22 deletions
+27 -1
View File
@@ -1004,7 +1004,7 @@ int free_and_strdup(char **p, const char *s) {
assert(p);
/* Replaces a string pointer with an strdup()ed new string,
/* Replaces a string pointer with a strdup()ed new string,
* possibly freeing the old one. */
if (streq_ptr(*p, s))
@@ -1023,6 +1023,32 @@ int free_and_strdup(char **p, const char *s) {
return 1;
}
int free_and_strndup(char **p, const char *s, size_t l) {
char *t;
assert(p);
assert(s || l == 0);
/* Replaces a string pointer with a strndup()ed new string,
* freeing the old one. */
if (!*p && !s)
return 0;
if (*p && s && strneq(*p, s, l) && (l > strlen(*p) || (*p)[l] == '\0'))
return 0;
if (s) {
t = strndup(s, l);
if (!t)
return -ENOMEM;
} else
t = NULL;
free_and_replace(*p, t);
return 1;
}
#if !HAVE_EXPLICIT_BZERO
/*
* Pointer to memset is volatile so that compiler must de-reference