summaryrefslogtreecommitdiff
path: root/src/basic/string-util.c
diff options
context:
space:
mode:
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2018-07-09 07:03:01 +0200
committerSven Eden <sven.eden@prydeworx.com>2018-10-29 10:18:27 +0100
commit081232081ccb96d2361834625caba4d3d2341437 (patch)
tree7f115420e77b9bb903a9f0e640d39020865a87e2 /src/basic/string-util.c
parent4ac4caa2cf2ee617c1b9b53246aa07cb8bf54154 (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/string-util.c')
-rw-r--r--src/basic/string-util.c28
1 files changed, 27 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