diff options
| author | Jeff Hostetler <jeffhost@microsoft.com> | 2015-01-08 17:24:12 -0500 |
|---|---|---|
| committer | Carlos MartÃn Nieto <cmn@dwim.me> | 2015-01-09 16:46:44 +0100 |
| commit | 4b1018d24f980273528743c27c47ceb96cb720bd (patch) | |
| tree | 24ad8913349b1755065eac2c1ab757f40f1a8cd5 | |
| parent | 56065c0954bc7bf6a28cb0a0534b26536b5361ea (diff) | |
| download | libgit2-4b1018d24f980273528743c27c47ceb96cb720bd.tar.gz | |
Fix crash in free() when git_buf_grow() fails.
| -rw-r--r-- | src/buffer.c | 3 | ||||
| -rw-r--r-- | tests/buf/oom.c | 31 |
2 files changed, 33 insertions, 1 deletions
diff --git a/src/buffer.c b/src/buffer.c index 7744d8f49..8013457c5 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -67,7 +67,8 @@ int git_buf_try_grow( if (!new_ptr) { if (mark_oom) { - if (buf->ptr) git__free(buf->ptr); + if (buf->ptr && (buf->ptr != git_buf__initbuf)) + git__free(buf->ptr); buf->ptr = git_buf__oom; } return -1; diff --git a/tests/buf/oom.c b/tests/buf/oom.c new file mode 100644 index 000000000..709439aa5 --- /dev/null +++ b/tests/buf/oom.c @@ -0,0 +1,31 @@ +#include "clar_libgit2.h" +#include "buffer.h" + +#if defined(GIT_ARCH_64) +#define TOOBIG 0xffffffffffffff00 +#else +#define TOOBIG 0xffffff00 +#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. + */ +void test_buf_oom__grow(void) +{ + git_buf buf = GIT_BUF_INIT; + + git_buf_clear(&buf); + + cl_assert(git_buf_grow(&buf, TOOBIG) == -1); + cl_assert(git_buf_oom(&buf)); + + git_buf_free(&buf); +} |
