From ca2857d81b5783b03d32ddc9d6f338bfec8d93dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn=20Nieto?= Date: Wed, 10 Jun 2015 10:30:08 +0200 Subject: [PATCH 1/4] merge: actually increment the counts, not the pointers `merge_diff_list_count_candidates()` takes pointers to the source and target counts, but when it comes time to increase them, we're increasing the pointer, rather than the value it's pointing to. Dereference the value to increase. --- src/merge.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/merge.c b/src/merge.c index 28fca0038..517d317de 100644 --- a/src/merge.c +++ b/src/merge.c @@ -1143,9 +1143,9 @@ static void merge_diff_list_count_candidates( if (GIT_MERGE_INDEX_ENTRY_EXISTS(entry->ancestor_entry) && (!GIT_MERGE_INDEX_ENTRY_EXISTS(entry->our_entry) || !GIT_MERGE_INDEX_ENTRY_EXISTS(entry->their_entry))) - src_count++; + (*src_count)++; else if (!GIT_MERGE_INDEX_ENTRY_EXISTS(entry->ancestor_entry)) - tgt_count++; + (*tgt_count)++; } } From 878293f7e1d62b951aaa7dc106ca9c6783112d96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn=20Nieto?= Date: Wed, 10 Jun 2015 10:44:14 +0200 Subject: [PATCH 2/4] pack: use git_buf when building the index name The way we currently do it depends on the subtlety of strlen vs sizeof and the fact that .pack is one longer than .idx. Let's use a git_buf so we can express the manipulation we want much more clearly. --- src/pack.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/src/pack.c b/src/pack.c index 105d67510..cd6526721 100644 --- a/src/pack.c +++ b/src/pack.c @@ -319,9 +319,9 @@ static int pack_index_check(const char *path, struct git_pack_file *p) static int pack_index_open(struct git_pack_file *p) { - char *idx_name; int error = 0; - size_t name_len, base_len; + size_t name_len; + git_buf idx_name = GIT_BUF_INIT; if (p->index_version > -1) return 0; @@ -329,22 +329,23 @@ static int pack_index_open(struct git_pack_file *p) name_len = strlen(p->pack_name); assert(name_len > strlen(".pack")); /* checked by git_pack_file alloc */ - if ((idx_name = git__malloc(name_len)) == NULL) + git_buf_grow(&idx_name, name_len); + git_buf_put(&idx_name, p->pack_name, name_len - strlen(".pack")); + git_buf_puts(&idx_name, ".idx"); + if (git_buf_oom(&idx_name)) { + giterr_set_oom(); return -1; - - base_len = name_len - strlen(".pack"); - memcpy(idx_name, p->pack_name, base_len); - memcpy(idx_name + base_len, ".idx", sizeof(".idx")); + } if ((error = git_mutex_lock(&p->lock)) < 0) { - git__free(idx_name); + git_buf_free(&idx_name); return error; } if (p->index_version == -1) - error = pack_index_check(idx_name, p); + error = pack_index_check(idx_name.ptr, p); - git__free(idx_name); + git_buf_free(&idx_name); git_mutex_unlock(&p->lock); From 969d4b703c910a8fd045baafbcd243b4c9825316 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn=20Nieto?= Date: Wed, 10 Jun 2015 10:59:56 +0200 Subject: [PATCH 3/4] object: correct the expected ID size in prefix lookup We take in a possibly partial ID by taking a length and working off of that to figure out whether to just look up the object or ask the backends for a prefix lookup. Unfortunately we've been checking the size against `GIT_OID_HEXSZ` which is the size of a *string* containing a full ID, whereas we need to check against the size we can have when it's a 20-byte array. Change the checks and comment to use `GIT_OID_RAWSZ` which is the correct size of a git_oid to have when full. --- src/object.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/object.c b/src/object.c index 1073559fd..a178e0ed3 100644 --- a/src/object.c +++ b/src/object.c @@ -129,10 +129,10 @@ int git_object_lookup_prefix( if (error < 0) return error; - if (len > GIT_OID_HEXSZ) - len = GIT_OID_HEXSZ; + if (len > GIT_OID_RAWSZ) + len = GIT_OID_RAWSZ; - if (len == GIT_OID_HEXSZ) { + if (len == GIT_OID_RAWSZ) { git_cached_obj *cached = NULL; /* We want to match the full id : we can first look up in the cache, @@ -172,9 +172,9 @@ int git_object_lookup_prefix( memcpy(short_oid.id, id->id, (len + 1) / 2); if (len % 2) short_oid.id[len / 2] &= 0xF0; - memset(short_oid.id + (len + 1) / 2, 0, (GIT_OID_HEXSZ - len) / 2); + memset(short_oid.id + (len + 1) / 2, 0, (GIT_OID_RAWSZ - len) / 2); - /* If len < GIT_OID_HEXSZ (a strict short oid was given), we have + /* If len < GIT_OID_RAWSZ (a strict short oid was given), we have * 2 options : * - We always search in the cache first. If we find that short oid is * ambiguous, we can stop. But in all the other cases, we must then From 0137aba56863634d81e407152df723d5ad4a97ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn=20Nieto?= Date: Wed, 10 Jun 2015 11:08:05 +0200 Subject: [PATCH 4/4] filter: close the descriptor in case of error When we hit an error writing to the next stream from a file, we jump to 'done' which currently skips over closing the file descriptor. Make sure to close the descriptor if it has been set to a valid value. --- src/filter.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/filter.c b/src/filter.c index c88fdd4ee..3c6a0a9d8 100644 --- a/src/filter.c +++ b/src/filter.c @@ -887,7 +887,7 @@ int git_filter_list_stream_file( git_vector filter_streams = GIT_VECTOR_INIT; git_writestream *stream_start; ssize_t readlen; - int fd, error; + int fd = -1, error; if ((error = stream_list_init( &stream_start, &filter_streams, filters, target)) < 0 || @@ -909,9 +909,10 @@ int git_filter_list_stream_file( else if (readlen < 0) error = readlen; - p_close(fd); done: + if (fd >= 0) + p_close(fd); stream_list_free(&filter_streams); git_buf_free(&abspath); return error;