From 00258cc0b6d54f8c5802b41089d9c6b74ba2f919 Mon Sep 17 00:00:00 2001 From: Jiri Pospisil Date: Thu, 6 Mar 2014 22:10:17 +0100 Subject: [PATCH 1/2] git_oid_fromstrn: Simplify the implementation and fix memory access issues --- src/oid.c | 24 +++++++++--------------- 1 file changed, 9 insertions(+), 15 deletions(-) diff --git a/src/oid.c b/src/oid.c index f74c43fe2..b640cadd1 100644 --- a/src/oid.c +++ b/src/oid.c @@ -24,30 +24,24 @@ int git_oid_fromstrn(git_oid *out, const char *str, size_t length) size_t p; int v; + assert(out && str); + + if (!length) + return oid_error_invalid("too short"); + if (length > GIT_OID_HEXSZ) return oid_error_invalid("too long"); - for (p = 0; p < length - 1; p += 2) { - v = (git__fromhex(str[p + 0]) << 4) - | git__fromhex(str[p + 1]); + memset(out->id, 0, GIT_OID_RAWSZ); + for (p = 0; p < length; p++) { + v = git__fromhex(str[p]); if (v < 0) return oid_error_invalid("contains invalid characters"); - out->id[p / 2] = (unsigned char)v; + out->id[p / 2] |= (unsigned char)(v << (p % 2 ? 0 : 4)); } - if (length % 2) { - v = (git__fromhex(str[p + 0]) << 4); - if (v < 0) - return oid_error_invalid("contains invalid characters"); - - out->id[p / 2] = (unsigned char)v; - p += 2; - } - - memset(out->id + p / 2, 0, (GIT_OID_HEXSZ - p) / 2); - return 0; } From 79aa03020d1a2020b4189ad272ee603af34f0921 Mon Sep 17 00:00:00 2001 From: Jiri Pospisil Date: Thu, 6 Mar 2014 22:23:57 +0100 Subject: [PATCH 2/2] blame: Fix compare function's data types Previously the hunk_byfinalline_search_cmp function was called with different data types (size_t and uint32_t) for the key argument but expected only the former resulting in an invalid memory access when passed the latter on a 64 bit machine. The following patch makes sure that the function is called and works with the same type (size_t). --- src/blame.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/blame.c b/src/blame.c index 01f88b729..e45c0ee1c 100644 --- a/src/blame.c +++ b/src/blame.c @@ -20,12 +20,15 @@ static int hunk_byfinalline_search_cmp(const void *key, const void *entry) { - uint16_t lineno = (uint16_t)*(size_t*)key; git_blame_hunk *hunk = (git_blame_hunk*)entry; - if (lineno < hunk->final_start_line_number) + size_t lineno = *(size_t*)key; + size_t lines_in_hunk = (size_t)hunk->lines_in_hunk; + size_t final_start_line_number = (size_t)hunk->final_start_line_number; + + if (lineno < final_start_line_number) return -1; - if (lineno >= hunk->final_start_line_number + hunk->lines_in_hunk) + if (lineno >= final_start_line_number + lines_in_hunk) return 1; return 0; } @@ -95,7 +98,7 @@ static void shift_hunks_by(git_vector *v, size_t start_line, int shift_by) { size_t i; - if (!git_vector_bsearch2( &i, v, hunk_byfinalline_search_cmp, &start_line)) { + if (!git_vector_bsearch2(&i, v, hunk_byfinalline_search_cmp, &start_line)) { for (; i < v->length; i++) { git_blame_hunk *hunk = (git_blame_hunk*)v->contents[i]; hunk->final_start_line_number += shift_by; @@ -161,10 +164,10 @@ const git_blame_hunk *git_blame_get_hunk_byindex(git_blame *blame, uint32_t inde const git_blame_hunk *git_blame_get_hunk_byline(git_blame *blame, uint32_t lineno) { - size_t i; + size_t i, new_lineno = (size_t)lineno; assert(blame); - if (!git_vector_bsearch2( &i, &blame->hunks, hunk_byfinalline_search_cmp, &lineno)) { + if (!git_vector_bsearch2(&i, &blame->hunks, hunk_byfinalline_search_cmp, &new_lineno)) { return git_blame_get_hunk_byindex(blame, (uint32_t)i); }