diff --git a/src/oid.c b/src/oid.c index e2d16d537..b47fa2c77 100644 --- a/src/oid.c +++ b/src/oid.c @@ -34,15 +34,16 @@ static char to_hex[] = "0123456789abcdef"; int git_oid_fromstrn(git_oid *out, const char *str, size_t length) { size_t p; + int v; + + if (length < 4) + return git__throw(GIT_ENOTOID, "Failed to generate sha1. Given string is too short"); if (length > GIT_OID_HEXSZ) length = GIT_OID_HEXSZ; - if (length % 2) - length--; - - for (p = 0; p < length; p += 2) { - int v = (from_hex[(unsigned char)str[p + 0]] << 4) + for (p = 0; p < length - 1; p += 2) { + v = (from_hex[(unsigned char)str[p + 0]] << 4) | from_hex[(unsigned char)str[p + 1]]; if (v < 0) @@ -51,8 +52,16 @@ int git_oid_fromstrn(git_oid *out, const char *str, size_t length) out->id[p / 2] = (unsigned char)v; } - for (; p < GIT_OID_HEXSZ; p += 2) - out->id[p / 2] = 0x0; + if (length % 2) { + v = (from_hex[(unsigned char)str[p + 0]] << 4); + if (v < 0) + return git__throw(GIT_ENOTOID, "Failed to generate sha1. Given string is not a valid sha1 hash"); + + out->id[p / 2] = (unsigned char)v; + p += 2; + } + + memset(out->id + p / 2, 0, (GIT_OID_HEXSZ - p) / 2); return GIT_SUCCESS; }