Unverified Commit 11945461 by Patrick Steinhardt Committed by GitHub

Merge pull request #4854 from libgit2/ethomson/buf_oom_test

 buf::oom tests: use custom allocator for oom failures
parents 671b2446 2e34efaa
......@@ -364,7 +364,8 @@ typedef enum {
*
* > Set the memory allocator to a different memory allocator. This
* > allocator will then be used to make all memory allocations for
* > libgit2 operations.
* > libgit2 operations. If the given `allocator` is NULL, then the
* > system default will be restored.
*
* opts(GIT_OPT_ENABLE_UNSAVED_INDEX_SAFETY, int enabled)
*
......
......@@ -15,6 +15,15 @@
git_allocator git__allocator;
static int setup_default_allocator(void)
{
#if defined(GIT_MSVC_CRTDBG)
return git_win32_crtdbg_init_allocator(&git__allocator);
#else
return git_stdalloc_init_allocator(&git__allocator);
#endif
}
int git_allocator_global_init(void)
{
/*
......@@ -24,15 +33,14 @@ int git_allocator_global_init(void)
if (git__allocator.gmalloc != NULL)
return 0;
#if defined(GIT_MSVC_CRTDBG)
return git_win32_crtdbg_init_allocator(&git__allocator);
#else
return git_stdalloc_init_allocator(&git__allocator);
#endif
return setup_default_allocator();
}
int git_allocator_setup(git_allocator *allocator)
{
if (!allocator)
return setup_default_allocator();
memcpy(&git__allocator, allocator, sizeof(*allocator));
return 0;
}
......
#include "clar_libgit2.h"
#include "buffer.h"
/*
* We want to use some ridiculous size that `malloc` will fail with
* but that does not otherwise interfere with testing. On Linux, choose
* a number that is large enough to fail immediately but small enough
* that valgrind doesn't believe it to erroneously be a negative number.
* On macOS, choose a number that is large enough to fail immediately
* without having libc print warnings to stderr.
*/
#if defined(GIT_ARCH_64) && defined(__linux__)
# define TOOBIG 0x0fffffffffffffff
#elif defined(GIT_ARCH_64)
# define TOOBIG 0xffffffffffffff00
#endif
/**
* If we make a ridiculously large request the first time we
* actually allocate some space in the git_buf, the realloc()
* will fail. And because the git_buf_grow() wrapper always
* sets mark_oom, the code in git_buf_try_grow() will free
* the internal buffer and set it to git_buf__oom.
*
* We initialized the internal buffer to (the static variable)
* git_buf__initbuf. The purpose of this test is to make sure
* that we don't try to free the static buffer.
*
* Skip this test entirely on 32-bit platforms; a buffer large enough
* to guarantee malloc failures is so large that valgrind considers
* it likely to be an error.
*/
/* Override default allocators with ones that will fail predictably. */
static git_allocator std_alloc;
static git_allocator oom_alloc;
static void *oom_malloc(size_t n, const char *file, int line)
{
/* Reject any allocation of more than 100 bytes */
return (n > 100) ? NULL : std_alloc.gmalloc(n, file, line);
}
static void *oom_realloc(void *p, size_t n, const char *file, int line)
{
/* Reject any allocation of more than 100 bytes */
return (n > 100) ? NULL : std_alloc.grealloc(p, n, file, line);
}
void test_buf_oom__initialize(void)
{
git_stdalloc_init_allocator(&std_alloc);
git_stdalloc_init_allocator(&oom_alloc);
oom_alloc.gmalloc = oom_malloc;
oom_alloc.grealloc = oom_realloc;
cl_git_pass(git_libgit2_opts(GIT_OPT_SET_ALLOCATOR, &oom_alloc));
}
void test_buf_oom__cleanup(void)
{
cl_git_pass(git_libgit2_opts(GIT_OPT_SET_ALLOCATOR, NULL));
}
void test_buf_oom__grow(void)
{
#ifdef GIT_ARCH_64
git_buf buf = GIT_BUF_INIT;
git_buf_clear(&buf);
cl_git_pass(git_buf_grow(&buf, 42));
cl_assert(!git_buf_oom(&buf));
cl_assert(git_buf_grow(&buf, TOOBIG) == -1);
cl_assert(git_buf_grow(&buf, 101) == -1);
cl_assert(git_buf_oom(&buf));
git_buf_dispose(&buf);
#else
cl_skip();
#endif
}
void test_buf_oom__grow_by(void)
{
git_buf buf = GIT_BUF_INIT;
buf.size = SIZE_MAX-10;
cl_git_pass(git_buf_grow_by(&buf, 42));
cl_assert(!git_buf_oom(&buf));
cl_assert(git_buf_grow_by(&buf, 50) == -1);
cl_assert(git_buf_grow_by(&buf, 101) == -1);
cl_assert(git_buf_oom(&buf));
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment