Add reallocarray(3).
Originally a BSD extension, now in glibc too. We've used it internally
for a while.
(cherry-pick of e4b13f7e3ca68edfcc5faedc5e7d4e13c4e8edb9.)
Bug: http://b/112163459
Test: ran tests
Change-Id: I813c3a62b13ddb91ba41e32a5a853d09207ea6bc
Merged-In: I813c3a62b13ddb91ba41e32a5a853d09207ea6bc
diff --git a/tests/malloc_test.cpp b/tests/malloc_test.cpp
index 4161c90..c4f13f6 100644
--- a/tests/malloc_test.cpp
+++ b/tests/malloc_test.cpp
@@ -26,6 +26,12 @@
#include "private/bionic_config.h"
+#if defined(__BIONIC__)
+#define HAVE_REALLOCARRAY 1
+#else
+#define HAVE_REALLOCARRAY __GLIBC_PREREQ(2, 26)
+#endif
+
TEST(malloc, malloc_std) {
// Simple malloc test.
void *ptr = malloc(100);
@@ -497,3 +503,31 @@
// mallopt doesn't set errno.
ASSERT_EQ(0, errno);
}
+
+TEST(malloc, reallocarray_overflow) {
+#if HAVE_REALLOCARRAY
+ // Values that cause overflow to a result small enough (8 on LP64) that malloc would "succeed".
+ size_t a = static_cast<size_t>(INTPTR_MIN + 4);
+ size_t b = 2;
+
+ errno = 0;
+ ASSERT_TRUE(reallocarray(nullptr, a, b) == nullptr);
+ ASSERT_EQ(ENOMEM, errno);
+
+ errno = 0;
+ ASSERT_TRUE(reallocarray(nullptr, b, a) == nullptr);
+ ASSERT_EQ(ENOMEM, errno);
+#else
+ GTEST_LOG_(INFO) << "This test requires a C library with reallocarray.\n";
+#endif
+}
+
+TEST(malloc, reallocarray) {
+#if HAVE_REALLOCARRAY
+ void* p = reallocarray(nullptr, 2, 32);
+ ASSERT_TRUE(p != nullptr);
+ ASSERT_GE(malloc_usable_size(p), 64U);
+#else
+ GTEST_LOG_(INFO) << "This test requires a C library with reallocarray.\n";
+#endif
+}