avoid pointer arithmetic involving NULL in FLEX_ALLOC_MEM
authorRené Scharfe <l.s.r@web.de>
Sat, 15 Oct 2016 16:23:11 +0000 (18:23 +0200)
committerJunio C Hamano <gitster@pobox.com>
Mon, 17 Oct 2016 21:42:31 +0000 (14:42 -0700)
Calculating offsets involving a NULL pointer is undefined. It works in
practice (for now?), but we should not rely on it. Allocate first and
then simply refer to the flexible array member by its name instead of
performing pointer arithmetic up front. The resulting code is slightly
shorter, easier to read and doesn't rely on undefined behaviour.

NB: The cast to a (non-const) void pointer is necessary to keep support
for flexible array members declared as const.

Signed-off-by: Rene Scharfe <l.s.r@web.de>
Reviewed-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
git-compat-util.h
index 17918d028a25a19bc4fd55db51b9418b2881b68a..237cef17609529fab29d0c94a85ef78267cc4ace 100644 (file)
@@ -815,8 +815,9 @@ extern FILE *fopen_for_writing(const char *path);
  * times, and it must be assignable as an lvalue.
  */
 #define FLEX_ALLOC_MEM(x, flexname, buf, len) do { \
-       (x) = NULL; /* silence -Wuninitialized for offset calculation */ \
-       (x) = xalloc_flex(sizeof(*(x)), (char *)(&((x)->flexname)) - (char *)(x), (buf), (len)); \
+       size_t flex_array_len_ = (len); \
+       (x) = xcalloc(1, st_add3(sizeof(*(x)), flex_array_len_, 1)); \
+       memcpy((void *)(x)->flexname, (buf), flex_array_len_); \
 } while (0)
 #define FLEXPTR_ALLOC_MEM(x, ptrname, buf, len) do { \
        (x) = xalloc_flex(sizeof(*(x)), sizeof(*(x)), (buf), (len)); \