Commit 628edd6b1b41b23e79a821229569880d5c9dfcc7

Vicent Marti 2014-03-07T16:26:58

Merge pull request #2167 from mekishizufu/memory_access_fixes Fun with memory access

diff --git a/src/blame.c b/src/blame.c
index 01f88b7..e45c0ee 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);
 	}
 
diff --git a/src/oid.c b/src/oid.c
index f74c43f..b640cad 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;
 
-	if (length > GIT_OID_HEXSZ)
-		return oid_error_invalid("too long");
+	assert(out && str);
 
-	for (p = 0; p < length - 1; p += 2) {
-		v = (git__fromhex(str[p + 0]) << 4)
-				| git__fromhex(str[p + 1]);
+	if (!length)
+		return oid_error_invalid("too short");
 
-		if (v < 0)
-			return oid_error_invalid("contains invalid characters");
+	if (length > GIT_OID_HEXSZ)
+		return oid_error_invalid("too long");
 
-		out->id[p / 2] = (unsigned char)v;
-	}
+	memset(out->id, 0, GIT_OID_RAWSZ);
 
-	if (length % 2) {
-		v = (git__fromhex(str[p + 0]) << 4);
+	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;
-		p += 2;
+		out->id[p / 2] |= (unsigned char)(v << (p % 2 ? 0 : 4));
 	}
 
-	memset(out->id + p / 2, 0, (GIT_OID_HEXSZ - p) / 2);
-
 	return 0;
 }