summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2017-07-20 14:14:55 +0200
committerLennart Poettering <lennart@poettering.net>2017-07-31 18:20:28 +0200
commitc165d97d16f24c9c28d9574ed82b3a6669408ca5 (patch)
treeea76f32ddd66fad78c58d36e26af1784740d34b0
parent7bf7ce28b5a1f589f0f2382e54c03ab9b0794fab (diff)
downloadsystemd-c165d97d16f24c9c28d9574ed82b3a6669408ca5.tar.gz
alloc-util: add new helpers memdup_suffix0() and newdup_suffix0()
These are similar to memdup() and newdup(), but reserve one extra NUL byte at the end of the new allocation and initialize it. It's useful when copying out data from fixed size character arrays where NUL termination can't be assumed.
-rw-r--r--src/basic/alloc-util.c27
-rw-r--r--src/basic/alloc-util.h10
-rw-r--r--src/shared/logs-show.c7
3 files changed, 34 insertions, 10 deletions
diff --git a/src/basic/alloc-util.c b/src/basic/alloc-util.c
index b540dcddf5..948389f276 100644
--- a/src/basic/alloc-util.c
+++ b/src/basic/alloc-util.c
@@ -25,16 +25,31 @@
#include "util.h"
void* memdup(const void *p, size_t l) {
- void *r;
+ void *ret;
- assert(p);
+ assert(l == 0 || p);
+
+ ret = malloc(l);
+ if (!ret)
+ return NULL;
+
+ memcpy(ret, p, l);
+ return ret;
+}
+
+void* memdup_suffix0(const void*p, size_t l) {
+ void *ret;
+
+ assert(l == 0 || p);
+
+ /* The same as memdup() but place a safety NUL byte after the allocated memory */
- r = malloc(l);
- if (!r)
+ ret = malloc(l + 1);
+ if (!ret)
return NULL;
- memcpy(r, p, l);
- return r;
+ *((uint8_t*) mempcpy(ret, p, l)) = 0;
+ return ret;
}
void* greedy_realloc(void **p, size_t *allocated, size_t need, size_t size) {
diff --git a/src/basic/alloc-util.h b/src/basic/alloc-util.h
index a44dd473c1..0a89691bae 100644
--- a/src/basic/alloc-util.h
+++ b/src/basic/alloc-util.h
@@ -36,6 +36,8 @@
#define newdup(t, p, n) ((t*) memdup_multiply(p, sizeof(t), (n)))
+#define newdup_suffix0(t, p, n) ((t*) memdup_suffix0_multiply(p, sizeof(t), (n)))
+
#define malloc0(n) (calloc(1, (n)))
static inline void *mfree(void *memory) {
@@ -52,6 +54,7 @@ static inline void *mfree(void *memory) {
})
void* memdup(const void *p, size_t l) _alloc_(2);
+void* memdup_suffix0(const void*p, size_t l) _alloc_(2);
static inline void freep(void *p) {
free(*(void**) p);
@@ -84,6 +87,13 @@ _alloc_(2, 3) static inline void *memdup_multiply(const void *p, size_t size, si
return memdup(p, size * need);
}
+_alloc_(2, 3) static inline void *memdup_suffix0_multiply(const void *p, size_t size, size_t need) {
+ if (size_multiply_overflow(size, need))
+ return NULL;
+
+ return memdup_suffix0(p, size * need);
+}
+
void* greedy_realloc(void **p, size_t *allocated, size_t need, size_t size);
void* greedy_realloc0(void **p, size_t *allocated, size_t need, size_t size);
diff --git a/src/shared/logs-show.c b/src/shared/logs-show.c
index 02ae4265c6..54516cfb96 100644
--- a/src/shared/logs-show.c
+++ b/src/shared/logs-show.c
@@ -95,13 +95,12 @@ static int parse_field(const void *data, size_t length, const char *field, char
return 0;
nl = length - fl;
- buf = new(char, nl+1);
+
+
+ buf = newdup_suffix0(char, (const char*) data + fl, nl);
if (!buf)
return log_oom();
- memcpy(buf, (const char*) data + fl, nl);
- buf[nl] = 0;
-
free(*target);
*target = buf;