diff options
author | Russell Belfer <rb@github.com> | 2014-05-12 10:44:13 -0700 |
---|---|---|
committer | Russell Belfer <rb@github.com> | 2014-05-12 10:44:13 -0700 |
commit | af567e8853e359df3b3abb7d3f7c15c3b1b391c7 (patch) | |
tree | b107914c977657dbe32c76cedea7d44e88f80a8d | |
parent | ce3b71d91b9cac3b462dec9ac2c7e397b55c00a6 (diff) | |
parent | 1e4976cb015bd10a2a8c377e02801306473afc26 (diff) | |
download | libgit2-af567e8853e359df3b3abb7d3f7c15c3b1b391c7.tar.gz |
Merge pull request #2334 from libgit2/rb/fix-2333
Be more careful with user-supplied buffers
-rw-r--r-- | src/buffer.c | 37 | ||||
-rw-r--r-- | src/config.c | 3 | ||||
-rw-r--r-- | src/diff_print.c | 6 | ||||
-rw-r--r-- | src/filter.c | 5 | ||||
-rw-r--r-- | src/pack-objects.c | 1 | ||||
-rw-r--r-- | src/submodule.c | 4 | ||||
-rw-r--r-- | tests/object/blob/filter.c | 13 |
7 files changed, 46 insertions, 23 deletions
diff --git a/src/buffer.c b/src/buffer.c index 5169c3e09..b8f8660ed 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -104,17 +104,20 @@ void git_buf_free(git_buf *buf) void git_buf_sanitize(git_buf *buf) { if (buf->ptr == NULL) { - assert (buf->size == 0 && buf->asize == 0); + assert(buf->size == 0 && buf->asize == 0); buf->ptr = git_buf__initbuf; - } + } else if (buf->asize > buf->size) + buf->ptr[buf->size] = '\0'; } void git_buf_clear(git_buf *buf) { buf->size = 0; - if (!buf->ptr) + if (!buf->ptr) { buf->ptr = git_buf__initbuf; + buf->asize = 0; + } if (buf->asize > 0) buf->ptr[0] = '\0'; @@ -129,8 +132,11 @@ int git_buf_set(git_buf *buf, const void *data, size_t len) ENSURE_SIZE(buf, len + 1); memmove(buf->ptr, data, len); } + buf->size = len; - buf->ptr[buf->size] = '\0'; + if (buf->asize > buf->size) + buf->ptr[buf->size] = '\0'; + } return 0; } @@ -326,19 +332,20 @@ void git_buf_consume(git_buf *buf, const char *end) void git_buf_truncate(git_buf *buf, size_t len) { - if (len < buf->size) { - buf->size = len; + if (len >= buf->size) + return; + + buf->size = len; + if (buf->size < buf->asize) buf->ptr[buf->size] = '\0'; - } } void git_buf_shorten(git_buf *buf, size_t amount) { - if (amount > buf->size) - amount = buf->size; - - buf->size = buf->size - amount; - buf->ptr[buf->size] = '\0'; + if (buf->size > amount) + git_buf_truncate(buf, buf->size - amount); + else + git_buf_clear(buf); } void git_buf_rtruncate_at_char(git_buf *buf, char separator) @@ -574,7 +581,8 @@ void git_buf_rtrim(git_buf *buf) buf->size--; } - buf->ptr[buf->size] = '\0'; + if (buf->asize > buf->size) + buf->ptr[buf->size] = '\0'; } int git_buf_cmp(const git_buf *a, const git_buf *b) @@ -598,8 +606,7 @@ int git_buf_splice( /* Ported from git.git * https://github.com/git/git/blob/16eed7c/strbuf.c#L159-176 */ - if (git_buf_grow(buf, git_buf_len(buf) + nb_to_insert - nb_to_remove) < 0) - return -1; + ENSURE_SIZE(buf, buf->size + nb_to_insert - nb_to_insert + 1); memmove(buf->ptr + where + nb_to_insert, buf->ptr + where + nb_to_remove, diff --git a/src/config.c b/src/config.c index 75ffb4000..757ff0387 100644 --- a/src/config.c +++ b/src/config.c @@ -999,16 +999,19 @@ void git_config_iterator_free(git_config_iterator *iter) int git_config_find_global(git_buf *path) { + git_buf_sanitize(path); return git_sysdir_find_global_file(path, GIT_CONFIG_FILENAME_GLOBAL); } int git_config_find_xdg(git_buf *path) { + git_buf_sanitize(path); return git_sysdir_find_xdg_file(path, GIT_CONFIG_FILENAME_XDG); } int git_config_find_system(git_buf *path) { + git_buf_sanitize(path); return git_sysdir_find_system_file(path, GIT_CONFIG_FILENAME_SYSTEM); } diff --git a/src/diff_print.c b/src/diff_print.c index 07c1f8577..08e1e7f90 100644 --- a/src/diff_print.c +++ b/src/diff_print.c @@ -597,9 +597,9 @@ int git_diff_print_callback__to_file_handle( } /* print a git_patch to a git_buf */ -int git_patch_to_buf( - git_buf *out, - git_patch *patch) +int git_patch_to_buf(git_buf *out, git_patch *patch) { + assert(out && patch); + git_buf_sanitize(out); return git_patch_print(patch, git_diff_print_callback__to_buf, out); } diff --git a/src/filter.c b/src/filter.c index 76d7b7b56..b9e4f9ec8 100644 --- a/src/filter.c +++ b/src/filter.c @@ -591,6 +591,9 @@ int git_filter_list_apply_to_data( git_buf *dbuffer[2], local = GIT_BUF_INIT; unsigned int si = 0; + git_buf_sanitize(tgt); + git_buf_sanitize(src); + if (!fl) return filter_list_out_buffer_from_raw(tgt, src->ptr, src->size); @@ -626,7 +629,7 @@ int git_filter_list_apply_to_data( /* PASSTHROUGH means filter decided not to process the buffer */ error = 0; } else if (!error) { - git_buf_shorten(dbuffer[di], 0); /* force NUL termination */ + git_buf_sanitize(dbuffer[di]); /* force NUL termination */ si = di; /* swap buffers */ } else { tgt->size = 0; diff --git a/src/pack-objects.c b/src/pack-objects.c index 8b6acee15..3d3330ae8 100644 --- a/src/pack-objects.c +++ b/src/pack-objects.c @@ -1278,6 +1278,7 @@ int git_packbuilder_foreach(git_packbuilder *pb, int (*cb)(void *buf, size_t siz int git_packbuilder_write_buf(git_buf *buf, git_packbuilder *pb) { PREPARE_PACK; + git_buf_sanitize(buf); return write_pack(pb, &write_pack_buf, buf); } diff --git a/src/submodule.c b/src/submodule.c index 5ddbfe828..b1291df8e 100644 --- a/src/submodule.c +++ b/src/submodule.c @@ -641,7 +641,9 @@ int git_submodule_resolve_url(git_buf *out, git_repository *repo, const char *ur { int error = 0; - assert(url); + assert(out && repo && url); + + git_buf_sanitize(out); if (git_path_is_relative(url)) { if (!(error = get_url_base(out, repo))) diff --git a/tests/object/blob/filter.c b/tests/object/blob/filter.c index 9798055cd..0aaaee6f3 100644 --- a/tests/object/blob/filter.c +++ b/tests/object/blob/filter.c @@ -112,7 +112,7 @@ void test_object_blob_filter__to_odb(void) git_config *cfg; int i; git_blob *blob; - git_buf out = GIT_BUF_INIT; + git_buf out = GIT_BUF_INIT, zeroed; cl_git_pass(git_repository_config(&cfg, g_repo)); cl_assert(cfg); @@ -127,13 +127,20 @@ void test_object_blob_filter__to_odb(void) for (i = 0; i < CRLF_NUM_TEST_OBJECTS; i++) { cl_git_pass(git_blob_lookup(&blob, g_repo, &g_crlf_oids[i])); + /* try once with allocated blob */ cl_git_pass(git_filter_list_apply_to_blob(&out, fl, blob)); - cl_assert_equal_sz(g_crlf_filtered[i].size, out.size); - cl_assert_equal_i( 0, memcmp(out.ptr, g_crlf_filtered[i].ptr, out.size)); + /* try again with zeroed blob */ + memset(&zeroed, 0, sizeof(zeroed)); + cl_git_pass(git_filter_list_apply_to_blob(&zeroed, fl, blob)); + cl_assert_equal_sz(g_crlf_filtered[i].size, zeroed.size); + cl_assert_equal_i( + 0, memcmp(zeroed.ptr, g_crlf_filtered[i].ptr, zeroed.size)); + git_buf_free(&zeroed); + git_blob_free(blob); } |