Commit 00258cc0b6d54f8c5802b41089d9c6b74ba2f919

Jiri Pospisil 2014-03-06T22:10:17

git_oid_fromstrn: Simplify the implementation and fix memory access issues

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;
 }