From 48e6b02be9b0639fdc25e17514f11d7ef141dfbc Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Mon, 19 Jul 2021 15:41:44 -0400 Subject: alloc: add GIT_DEBUG_STRICT_ALLOC Add `GIT_DEBUG_STRICT_ALLOC` to help identify problematic callers of allocation code that pass a `0` size to the allocators and then expect a non-`NULL` return. When given a 0-size allocation, `malloc` _may_ return either a `NULL` _or_ a pointer that is not writeable. Most systems return a non-`NULL` pointer; AIX is an outlier. We should be able to cope with this AIXy behavior, so this adds an option to emulate it. --- src/allocators/stdalloc.c | 51 +++++++++++++++++++++++++++++++++++++---------- 1 file changed, 41 insertions(+), 10 deletions(-) (limited to 'src/allocators/stdalloc.c') diff --git a/src/allocators/stdalloc.c b/src/allocators/stdalloc.c index c4938e32b..7215468b6 100644 --- a/src/allocators/stdalloc.c +++ b/src/allocators/stdalloc.c @@ -9,34 +9,56 @@ static void *stdalloc__malloc(size_t len, const char *file, int line) { - void *ptr = malloc(len); + void *ptr; GIT_UNUSED(file); GIT_UNUSED(line); - if (!ptr) git_error_set_oom(); +#ifdef GIT_DEBUG_STRICT_ALLOC + if (!len) + return NULL; +#endif + + ptr = malloc(len); + + if (!ptr) + git_error_set_oom(); + return ptr; } static void *stdalloc__calloc(size_t nelem, size_t elsize, const char *file, int line) { - void *ptr = calloc(nelem, elsize); + void *ptr; GIT_UNUSED(file); GIT_UNUSED(line); - if (!ptr) git_error_set_oom(); +#ifdef GIT_DEBUG_STRICT_ALLOC + if (!elsize) + return NULL; +#endif + + ptr = calloc(nelem, elsize); + + if (!ptr) + git_error_set_oom(); + return ptr; } static char *stdalloc__strdup(const char *str, const char *file, int line) { - char *ptr = strdup(str); + char *ptr; GIT_UNUSED(file); GIT_UNUSED(line); - if (!ptr) git_error_set_oom(); + ptr = strdup(str); + + if (!ptr) + git_error_set_oom(); + return ptr; } @@ -48,7 +70,7 @@ static char *stdalloc__strndup(const char *str, size_t n, const char *file, int length = p_strnlen(str, n); if (GIT_ADD_SIZET_OVERFLOW(&alloclength, length, 1) || - !(ptr = stdalloc__malloc(alloclength, file, line))) + !(ptr = stdalloc__malloc(alloclength, file, line))) return NULL; if (length) @@ -65,7 +87,7 @@ static char *stdalloc__substrdup(const char *start, size_t n, const char *file, size_t alloclen; if (GIT_ADD_SIZET_OVERFLOW(&alloclen, n, 1) || - !(ptr = stdalloc__malloc(alloclen, file, line))) + !(ptr = stdalloc__malloc(alloclen, file, line))) return NULL; memcpy(ptr, start, n); @@ -75,12 +97,21 @@ static char *stdalloc__substrdup(const char *start, size_t n, const char *file, static void *stdalloc__realloc(void *ptr, size_t size, const char *file, int line) { - void *new_ptr = realloc(ptr, size); + void *new_ptr; GIT_UNUSED(file); GIT_UNUSED(line); - if (!new_ptr) git_error_set_oom(); +#ifdef GIT_DEBUG_STRICT_ALLOC + if (!size) + return NULL; +#endif + + new_ptr = realloc(ptr, size); + + if (!new_ptr) + git_error_set_oom(); + return new_ptr; } -- cgit v1.2.1