From 7d5bd1da7064cac25657fa46d2e0f839dacca5b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20Nie=C3=9Fen?= Date: Tue, 6 Sep 2022 15:46:56 +0000 Subject: [PATCH] src: remove UncheckedMalloc(0) workaround Assuming that UncheckedMalloc(0) returns a non-nullptr is non-standard and we use other allocators as well (e.g., OPENSSL_malloc) that do not guarantee this behavior. It is the caller's responsibility to check that size != 0 implies UncheckedMalloc(size) != nullptr, and that's exactly what the checked variants (Malloc etc.) already do. The current behavior is also inconsistent with UncheckedRealloc(), which always returns a nullptr when the size is 0, and with the documentation in src/README.md. Refs: https://github.com/nodejs/node/issues/8571 Refs: https://github.com/nodejs/node/pull/8572 --- src/util-inl.h | 2 -- test/cctest/test_util.cc | 42 ++++++++++++++++++++-------------------- 2 files changed, 21 insertions(+), 23 deletions(-) diff --git a/src/util-inl.h b/src/util-inl.h index caadba9dae2caa..d6b7bd5e1b4cd1 100644 --- a/src/util-inl.h +++ b/src/util-inl.h @@ -361,13 +361,11 @@ T* UncheckedRealloc(T* pointer, size_t n) { // As per spec realloc behaves like malloc if passed nullptr. template inline T* UncheckedMalloc(size_t n) { - if (n == 0) n = 1; return UncheckedRealloc(nullptr, n); } template inline T* UncheckedCalloc(size_t n) { - if (n == 0) n = 1; MultiplyWithOverflowCheck(sizeof(T), n); return static_cast(calloc(n, sizeof(T))); } diff --git a/test/cctest/test_util.cc b/test/cctest/test_util.cc index a64942a8a35009..c355fbca58e8a0 100644 --- a/test/cctest/test_util.cc +++ b/test/cctest/test_util.cc @@ -97,39 +97,39 @@ TEST(UtilTest, ToLower) { EXPECT_EQ('a', ToLower('A')); } -#define TEST_AND_FREE(expression) \ - do { \ - auto pointer = expression; \ - EXPECT_NE(nullptr, pointer); \ - free(pointer); \ +#define TEST_AND_FREE(expression, size) \ + do { \ + auto pointer = expression(size); \ + if (size != 0) EXPECT_NE(pointer, nullptr); \ + free(pointer); \ } while (0) TEST(UtilTest, Malloc) { - TEST_AND_FREE(Malloc(0)); - TEST_AND_FREE(Malloc(1)); - TEST_AND_FREE(Malloc(0)); - TEST_AND_FREE(Malloc(1)); + TEST_AND_FREE(Malloc, 0); + TEST_AND_FREE(Malloc, 1); + TEST_AND_FREE(Malloc, 0); + TEST_AND_FREE(Malloc, 1); } TEST(UtilTest, Calloc) { - TEST_AND_FREE(Calloc(0)); - TEST_AND_FREE(Calloc(1)); - TEST_AND_FREE(Calloc(0)); - TEST_AND_FREE(Calloc(1)); + TEST_AND_FREE(Calloc, 0); + TEST_AND_FREE(Calloc, 1); + TEST_AND_FREE(Calloc, 0); + TEST_AND_FREE(Calloc, 1); } TEST(UtilTest, UncheckedMalloc) { - TEST_AND_FREE(UncheckedMalloc(0)); - TEST_AND_FREE(UncheckedMalloc(1)); - TEST_AND_FREE(UncheckedMalloc(0)); - TEST_AND_FREE(UncheckedMalloc(1)); + TEST_AND_FREE(UncheckedMalloc, 0); + TEST_AND_FREE(UncheckedMalloc, 1); + TEST_AND_FREE(UncheckedMalloc, 0); + TEST_AND_FREE(UncheckedMalloc, 1); } TEST(UtilTest, UncheckedCalloc) { - TEST_AND_FREE(UncheckedCalloc(0)); - TEST_AND_FREE(UncheckedCalloc(1)); - TEST_AND_FREE(UncheckedCalloc(0)); - TEST_AND_FREE(UncheckedCalloc(1)); + TEST_AND_FREE(UncheckedCalloc, 0); + TEST_AND_FREE(UncheckedCalloc, 1); + TEST_AND_FREE(UncheckedCalloc, 0); + TEST_AND_FREE(UncheckedCalloc, 1); } template