diff options
author | Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> | 2018-07-09 07:03:01 +0200 |
---|---|---|
committer | Sven Eden <sven.eden@prydeworx.com> | 2018-10-29 10:18:27 +0100 |
commit | 081232081ccb96d2361834625caba4d3d2341437 (patch) | |
tree | 7f115420e77b9bb903a9f0e640d39020865a87e2 /src/basic | |
parent | 4ac4caa2cf2ee617c1b9b53246aa07cb8bf54154 (diff) |
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.
(cherry picked from commit 7f546026abbdc56c453a577e52d57159458c3e9c)
Diffstat (limited to 'src/basic')
-rw-r--r-- | src/basic/string-util.c | 28 | ||||
-rw-r--r-- | src/basic/string-util.h | 1 |
2 files changed, 28 insertions, 1 deletions
diff --git a/src/basic/string-util.c b/src/basic/string-util.c index d7ba43541..38adaaf45 100644 --- a/src/basic/string-util.c +++ b/src/basic/string-util.c @@ -1006,7 +1006,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)) @@ -1025,6 +1025,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 diff --git a/src/basic/string-util.h b/src/basic/string-util.h index 3cada129e..46760cbc1 100644 --- a/src/basic/string-util.h +++ b/src/basic/string-util.h @@ -182,6 +182,7 @@ char *strrep(const char *s, unsigned n); int split_pair(const char *s, const char *sep, char **l, char **r); int free_and_strdup(char **p, const char *s); +int free_and_strndup(char **p, const char *s, size_t l); /* Normal memmem() requires haystack to be nonnull, which is annoying for zero-length buffers */ static inline void *memmem_safe(const void *haystack, size_t haystacklen, const void *needle, size_t needlelen) { |