]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
alloc-util: add new helpers memdup_suffix0() and newdup_suffix0()
authorLennart Poettering <lennart@poettering.net>
Thu, 20 Jul 2017 12:14:55 +0000 (14:14 +0200)
committerLennart Poettering <lennart@poettering.net>
Mon, 31 Jul 2017 16:20:28 +0000 (18:20 +0200)
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.

src/basic/alloc-util.c
src/basic/alloc-util.h
src/shared/logs-show.c

index b540dcddf589fafb0b4de1cccbd162c5b10ad90e..948389f276cce82d7bfcdaea6d49f02a90039062 100644 (file)
 #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) {
index a44dd473c1106574472ae2cd84e7db7f2df935ae..0a89691baedd4fea597b5ea7c603c79a37a93d60 100644 (file)
@@ -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);
 
index 02ae4265c6b5ef0b67b02e89c2ec875d278db268..54516cfb9617afab210e5ea1cd99439c3da0c9b0 100644 (file)
@@ -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;