From f47a52ce85c3d8d559aaae7b7a426c359fbca225 Mon Sep 17 00:00:00 2001 From: HolyWu Date: Mon, 30 Apr 2018 15:41:50 +0800 Subject: [PATCH] Make _recalloc adhere to MS's definition --- src/tcmalloc.cc | 2 +- src/windows/override_functions.cc | 23 +++++++++++++++++++---- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/src/tcmalloc.cc b/src/tcmalloc.cc index 48d4530..37c1440 100644 --- a/src/tcmalloc.cc +++ b/src/tcmalloc.cc @@ -1391,7 +1391,7 @@ ATTRIBUTE_ALWAYS_INLINE inline void* do_calloc(size_t n, size_t elem_size) { void* result = do_malloc_or_cpp_alloc(size); if (result != NULL) { - memset(result, 0, size); + memset(result, 0, tc_nallocx(size, 0)); } return result; } diff --git a/src/windows/override_functions.cc b/src/windows/override_functions.cc index f6f519a..06c4c17 100644 --- a/src/windows/override_functions.cc +++ b/src/windows/override_functions.cc @@ -66,10 +66,25 @@ void* _calloc_base(size_t n, size_t size) { return calloc(n, size); } -void* _recalloc(void* p, size_t n, size_t size) { - void* result = realloc(p, n * size); - memset(result, 0, n * size); - return result; +void* _recalloc(void* old_ptr, size_t n, size_t size) { + // Ensure that (n * size) does not overflow + if (!(n == 0 || (std::numeric_limits::max)() / n >= size)) { + errno = ENOMEM; + return NULL; + } + + const size_t old_size = tc_malloc_size(old_ptr); + const size_t new_size = n * size; + + void* new_ptr = realloc(old_ptr, new_size); + + // If the reallocation succeeded and the new block is larger, zero-fill the + // new bytes: + if (new_ptr != NULL && new_size > old_size) { + memset(static_cast(new_ptr) + old_size, 0, tc_nallocx(new_size, 0) - old_size); + } + + return new_ptr; } void* _calloc_impl(size_t n, size_t size) {