diff options
Diffstat (limited to 'test/Alloc.c')
-rw-r--r-- | test/Alloc.c | 167 |
1 files changed, 167 insertions, 0 deletions
diff --git a/test/Alloc.c b/test/Alloc.c index 3120f0f..03f44a8 100644 --- a/test/Alloc.c +++ b/test/Alloc.c @@ -569,6 +569,166 @@ static void test_XtRealloc_overflow(void) } +/* Make sure XtReallocArray() works for a non-zero amount of memory */ +static void test_XtReallocArray_normal(void) +{ + void *p, *p2; + char *p3; + + errno = 0; + + /* Make sure reallocarray with a NULL pointer acts as malloc */ + p = XtReallocArray(NULL, 8, 14); + g_assert_nonnull(p); + CHECK_ALIGNMENT(p); + CHECK_SIZE(p, 8 * 14); + + /* make sure we can write to all the allocated memory */ + memset(p, 'A', 8 * 14); + + /* create another block after the first */ + p2 = XtMalloc(73); + g_assert_nonnull(p2); + + /* now resize the first */ + p3 = XtReallocArray(p, 73, 14); + g_assert_nonnull(p3); + CHECK_ALIGNMENT(p3); + CHECK_SIZE(p3, 73 * 14); + /* verify previous values are still present */ + for (int i = 0; i < (8 * 14); i++) { + g_assert_cmpint(p3[i], ==, 'A'); + } + + XtFree(p3); + XtFree(p2); + g_assert_cmpint(errno, ==, 0); +} + +/* Make sure XtReallocArray(0) returns a valid pointer as expected */ +static void test_XtReallocArray_zero(void) +{ + void *p, *p2; + + errno = 0; + + p = XtReallocArray(NULL, 0, 0); + g_assert_nonnull(p); + + p2 = XtReallocArray(p, 0, 0); +#ifdef MALLOC_0_RETURNS_NULL + g_assert_null(p); +#else + g_assert_nonnull(p); +#endif + + XtFree(p2); + g_assert_cmpint(errno, ==, 0); +} + +/* Make sure sizes larger than the limit we set in main() fail */ +static void test_XtReallocArray_oversize(void) +{ + void *p, *p2; + + /* Pick a number of elements between 1 & 16K */ + guint32 num = g_test_rand_int_range(1, (16 * 1024)); + /* Pick a size between 1 & 16K */ + guint32 size = g_test_rand_int_range(1, (16 * 1024)); + + p = XtReallocArray(NULL, num, size); + g_assert_nonnull(p); + CHECK_ALIGNMENT(p); + CHECK_SIZE(p, num * size); + + if (setjmp(jmp_env) == 0) { + p2 = XtReallocArray(p, 2, ALLOC_LIMIT); + g_assert_null(p2); + } else { + /* + * We jumped here from error handler as expected. + * We cannot verify errno here, as the Xt error handler makes + * calls that override errno, when trying to load error message + * files from different locations. + */ + } + + errno = 0; + XtFree(p); + g_assert_cmpint(errno, ==, 0); +} + +/* Make sure XtReallocArray catches integer overflow if possible, by requesting + * sizes that are so large that they cause overflows when either adding the + * reallocarray data block overhead or aligning. + * + * Testing integer overflow cases is limited by the fact that XtReallocArray + * only takes unsigned arguments (typically 32-bit), and relies on + * the underlying libc reallocarray to catch overflow, which can't occur if + * 32-bit arguments are passed to a function taking 64-bit args. + */ +static void test_XtReallocArray_overflow(void) +{ +#if UINT_MAX < SIZE_MAX + g_test_skip("overflow not possible in this config"); +#else + void *p, *p2; + + /* Pick a number of elements between 1 & 16K */ + guint32 num = g_test_rand_int_range(1, (16 * 1024)); + /* Pick a size between 1 & 16K */ + guint32 size = g_test_rand_int_range(1, (16 * 1024)); + + p = XtReallocArray(NULL, num, size); + g_assert_nonnull(p); + CHECK_ALIGNMENT(p); + CHECK_SIZE(p, num * size); + + if (setjmp(jmp_env) == 0) { + p2 = XtReallocArray(p, 1, SIZE_MAX); + g_assert_null(p2); + } else { + /* + * We jumped here from error handler as expected. + * We cannot verify errno here, as the Xt error handler makes + * calls that override errno, when trying to load error message + * files from different locations. + */ + } + + if (setjmp(jmp_env) == 0) { + /* SQRT_SIZE_MAX * SQRT_SIZE_MAX == 0 due to overflow */ + p2 = XtReallocArray(p, SQRT_SIZE_MAX, SQRT_SIZE_MAX); + g_assert_null(p2); + } else { + /* + * We jumped here from error handler as expected. + * We cannot verify errno here, as the Xt error handler makes + * calls that override errno, when trying to load error message + * files from different locations. + */ + } + + if (setjmp(jmp_env) == 0) { + /* Overflows to a small positive number */ + p2 = XtReallocArray(p, SQRT_SIZE_MAX + 1, SQRT_SIZE_MAX); + g_assert_null(p2); + } else { + /* + * We jumped here from error handler as expected. + * We cannot verify errno here, as the Xt error handler makes + * calls that override errno, when trying to load error message + * files from different locations. + */ + } + + errno = 0; + XtFree(p); + g_assert_cmpint(errno, ==, 0); +#endif +} + + int main(int argc, char** argv) { struct rlimit lim; @@ -606,5 +766,12 @@ int main(int argc, char** argv) g_test_add_func("/Alloc/XtRealloc/oversize", test_XtRealloc_oversize); g_test_add_func("/Alloc/XtRealloc/overflow", test_XtRealloc_overflow); + g_test_add_func("/Alloc/XtReallocArray/normal", test_XtReallocArray_normal); + g_test_add_func("/Alloc/XtReallocArray/zero", test_XtReallocArray_zero); + g_test_add_func("/Alloc/XtReallocArray/oversize", + test_XtReallocArray_oversize); + g_test_add_func("/Alloc/XtReallocArray/overflow", + test_XtReallocArray_overflow); + return g_test_run(); } |