diff options
-rw-r--r-- | fuzzers/corpora/midx/666a779eed16847c6930a71c0547a34e52db409e | bin | 0 -> 62 bytes | |||
-rw-r--r-- | src/diff_print.c | 5 | ||||
-rw-r--r-- | src/fetch.c | 7 | ||||
-rw-r--r-- | src/midx.c | 11 | ||||
-rw-r--r-- | src/remote.c | 7 | ||||
-rw-r--r-- | tests/diff/parse.c | 26 | ||||
-rw-r--r-- | tests/online/fetch.c | 29 | ||||
-rw-r--r-- | tests/patch/patch_common.h | 9 |
8 files changed, 87 insertions, 7 deletions
diff --git a/fuzzers/corpora/midx/666a779eed16847c6930a71c0547a34e52db409e b/fuzzers/corpora/midx/666a779eed16847c6930a71c0547a34e52db409e Binary files differnew file mode 100644 index 000000000..ed9e0d07a --- /dev/null +++ b/fuzzers/corpora/midx/666a779eed16847c6930a71c0547a34e52db409e diff --git a/src/diff_print.c b/src/diff_print.c index 03d25b087..6c5a2cdc8 100644 --- a/src/diff_print.c +++ b/src/diff_print.c @@ -316,6 +316,11 @@ static int diff_print_oid_range( static int diff_delta_format_path( git_str *out, const char *prefix, const char *filename) { + if (!filename) { + /* don't prefix "/dev/null" */ + return git_str_puts(out, "/dev/null"); + } + if (git_str_joinpath(out, prefix, filename) < 0) return -1; diff --git a/src/fetch.c b/src/fetch.c index 03d38452c..e9f30d9bc 100644 --- a/src/fetch.c +++ b/src/fetch.c @@ -76,8 +76,11 @@ static int maybe_want_oid(git_remote *remote, git_refspec *spec) GIT_ERROR_CHECK_ALLOC(oid_head); git_oid_fromstr(&oid_head->oid, spec->src); - oid_head->name = git__strdup(spec->dst); - GIT_ERROR_CHECK_ALLOC(oid_head->name); + + if (spec->dst) { + oid_head->name = git__strdup(spec->dst); + GIT_ERROR_CHECK_ALLOC(oid_head->name); + } if (git_vector_insert(&remote->local_heads, oid_head) < 0 || git_vector_insert(&remote->refs, oid_head) < 0) diff --git a/src/midx.c b/src/midx.c index eb99e7373..0092601f6 100644 --- a/src/midx.c +++ b/src/midx.c @@ -225,8 +225,13 @@ int git_midx_parse( chunk_hdr = data + sizeof(struct git_midx_header); last_chunk = NULL; for (i = 0; i < hdr->chunks; ++i, chunk_hdr += 12) { - chunk_offset = ((off64_t)ntohl(*((uint32_t *)(chunk_hdr + 4)))) << 32 | - ((off64_t)ntohl(*((uint32_t *)(chunk_hdr + 8)))); + uint32_t chunk_id = ntohl(*((uint32_t *)(chunk_hdr + 0))); + uint64_t high_offset = ((uint64_t)ntohl(*((uint32_t *)(chunk_hdr + 4)))) & 0xffffffffu; + uint64_t low_offset = ((uint64_t)ntohl(*((uint32_t *)(chunk_hdr + 8)))) & 0xffffffffu; + + if (high_offset >= INT32_MAX) + return midx_error("chunk offset out of range"); + chunk_offset = (off64_t)(high_offset << 32 | low_offset); if (chunk_offset < last_chunk_offset) return midx_error("chunks are non-monotonic"); if (chunk_offset >= trailer_offset) @@ -235,7 +240,7 @@ int git_midx_parse( last_chunk->length = (size_t)(chunk_offset - last_chunk_offset); last_chunk_offset = chunk_offset; - switch (ntohl(*((uint32_t *)(chunk_hdr + 0)))) { + switch (chunk_id) { case MIDX_PACKFILE_NAMES_ID: chunk_packfile_names.offset = last_chunk_offset; last_chunk = &chunk_packfile_names; diff --git a/src/remote.c b/src/remote.c index f6421b9eb..1a79faaab 100644 --- a/src/remote.c +++ b/src/remote.c @@ -1895,8 +1895,11 @@ static int update_tips_for_spec( if (git_oid__is_hexstr(spec->src)) { git_oid id; - if ((error = git_oid_fromstr(&id, spec->src)) < 0 || - (error = update_ref(remote, spec->dst, &id, log_message, callbacks)) < 0) + if ((error = git_oid_fromstr(&id, spec->src)) < 0) + goto on_error; + + if (spec->dst && + (error = update_ref(remote, spec->dst, &id, log_message, callbacks)) < 0) goto on_error; git_oid_cpy(&oid_head.oid, &id); diff --git a/tests/diff/parse.c b/tests/diff/parse.c index d3a0c8de6..9c3f798e4 100644 --- a/tests/diff/parse.c +++ b/tests/diff/parse.c @@ -431,6 +431,32 @@ void test_diff_parse__new_file_with_space(void) git_diff_free(diff); } +void test_diff_parse__new_file_with_space_and_regenerate_patch(void) +{ + const char *content = PATCH_ORIGINAL_NEW_FILE_WITH_SPACE; + git_diff *diff = NULL; + git_buf buf = GIT_BUF_INIT; + + cl_git_pass(git_diff_from_buffer(&diff, content, strlen(content))); + cl_git_pass(git_diff_to_buf(&buf, diff, GIT_DIFF_FORMAT_PATCH)); + + git_buf_dispose(&buf); + git_diff_free(diff); +} + +void test_diff_parse__delete_file_with_space_and_regenerate_patch(void) +{ + const char *content = PATCH_DELETE_FILE_WITH_SPACE; + git_diff *diff = NULL; + git_buf buf = GIT_BUF_INIT; + + cl_git_pass(git_diff_from_buffer(&diff, content, strlen(content))); + cl_git_pass(git_diff_to_buf(&buf, diff, GIT_DIFF_FORMAT_PATCH)); + + git_buf_dispose(&buf); + git_diff_free(diff); +} + void test_diff_parse__crlf(void) { const char *text = PATCH_CRLF; diff --git a/tests/online/fetch.c b/tests/online/fetch.c index 7334f7e8b..5beb5b618 100644 --- a/tests/online/fetch.c +++ b/tests/online/fetch.c @@ -321,3 +321,32 @@ void test_online_fetch__reachable_commit(void) git_object_free(obj); git_remote_free(remote); } + +void test_online_fetch__reachable_commit_without_destination(void) +{ + git_remote *remote; + git_strarray refspecs; + git_object *obj; + git_oid expected_id; + git_str fetchhead = GIT_STR_INIT; + char *refspec = "2c349335b7f797072cf729c4f3bb0914ecb6dec9"; + + refspecs.strings = &refspec; + refspecs.count = 1; + + git_oid_fromstr(&expected_id, "2c349335b7f797072cf729c4f3bb0914ecb6dec9"); + + cl_git_pass(git_remote_create(&remote, _repo, "test", + "https://github.com/libgit2/TestGitRepository")); + cl_git_pass(git_remote_fetch(remote, &refspecs, NULL, NULL)); + + cl_git_fail_with(GIT_ENOTFOUND, git_revparse_single(&obj, _repo, "refs/success")); + + cl_git_pass(git_futils_readbuffer(&fetchhead, "./fetch/.git/FETCH_HEAD")); + cl_assert_equal_s(fetchhead.ptr, + "2c349335b7f797072cf729c4f3bb0914ecb6dec9\t\t'2c349335b7f797072cf729c4f3bb0914ecb6dec9' of https://github.com/libgit2/TestGitRepository\n"); + + git_str_dispose(&fetchhead); + git_object_free(obj); + git_remote_free(remote); +} diff --git a/tests/patch/patch_common.h b/tests/patch/patch_common.h index 1e03889fc..7e2cb6a58 100644 --- a/tests/patch/patch_common.h +++ b/tests/patch/patch_common.h @@ -933,6 +933,15 @@ "@@ -0,0 +1 @@\n" \ "+a\n" +#define PATCH_DELETE_FILE_WITH_SPACE \ + "diff --git a/sp ace.txt b/sp ace.txt\n" \ + "deleted file mode 100644\n" \ + "index 789819226..000000000\n" \ + "--- a/sp ace.txt\n" \ + "+++ /dev/null\n" \ + "@@ -1 +0,0 @@\n" \ + "-a\n" + #define PATCH_CRLF \ "diff --git a/test-file b/test-file\r\n" \ "new file mode 100644\r\n" \ |