diff options
author | Patrick Steinhardt <ps@pks.im> | 2018-10-25 11:17:52 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-10-25 11:17:52 +0200 |
commit | 1194546138cbbe3d822e4df2a41179a847099e75 (patch) | |
tree | d36a2ec606c4e1bc83c71f9b656301fc331bf661 | |
parent | 671b2446b7805089cbc9dad9db216d13938b1393 (diff) | |
parent | 2e34efaab1ec85a5a4ba522147edec9114d065d3 (diff) | |
download | libgit2-1194546138cbbe3d822e4df2a41179a847099e75.tar.gz |
Merge pull request #4854 from libgit2/ethomson/buf_oom_test
buf::oom tests: use custom allocator for oom failures
-rw-r--r-- | include/git2/common.h | 3 | ||||
-rw-r--r-- | src/alloc.c | 18 | ||||
-rw-r--r-- | tests/buf/oom.c | 76 |
3 files changed, 54 insertions, 43 deletions
diff --git a/include/git2/common.h b/include/git2/common.h index a14e0961e..152e23aae 100644 --- a/include/git2/common.h +++ b/include/git2/common.h @@ -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) * diff --git a/src/alloc.c b/src/alloc.c index d4e6f1ebd..0cac457d4 100644 --- a/src/alloc.c +++ b/src/alloc.c @@ -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; } diff --git a/tests/buf/oom.c b/tests/buf/oom.c index ec3bad997..726234ef8 100644 --- a/tests/buf/oom.c +++ b/tests/buf/oom.c @@ -1,57 +1,59 @@ #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)); } |