Commit d4e85a1a authored by Michael Haggerty's avatar Michael Haggerty Committed by Junio C Hamano

get_sha1_hex(): do not read past a NUL character

Previously, get_sha1_hex() would read one character past the end of a
null-terminated string whose strlen was an even number less than 40.
Although the function correctly returned -1 in these cases, the extra
memory access might have been to uninitialized (or even, conceivably,
unallocated) memory.

Add a check to avoid reading past the end of a string.

This problem was discovered by Thomas Rast <>
using valgrind.
Signed-off-by: default avatarMichael Haggerty <>
Signed-off-by: default avatarJunio C Hamano <>
parent 3793ac56
......@@ -819,7 +819,16 @@ static inline int get_sha1_with_context(const char *str, unsigned char *sha1, st
return get_sha1_with_context_1(str, sha1, orc, 0, NULL);
* Try to read a SHA1 in hexadecimal format from the 40 characters
* starting at hex. Write the 20-byte result to sha1 in binary form.
* Return 0 on success. Reading stops if a NUL is encountered in the
* input, so it is safe to pass this function an arbitrary
* null-terminated string.
extern int get_sha1_hex(const char *hex, unsigned char *sha1);
extern char *sha1_to_hex(const unsigned char *sha1); /* static buffer result! */
extern int read_ref(const char *filename, unsigned char *sha1);
extern const char *resolve_ref(const char *path, unsigned char *sha1, int, int *);
......@@ -39,7 +39,15 @@ int get_sha1_hex(const char *hex, unsigned char *sha1)
int i;
for (i = 0; i < 20; i++) {
unsigned int val = (hexval(hex[0]) << 4) | hexval(hex[1]);
unsigned int val;
* hex[1]=='\0' is caught when val is checked below,
* but if hex[0] is NUL we have to avoid reading
* past the end of the string:
if (!hex[0])
return -1;
val = (hexval(hex[0]) << 4) | hexval(hex[1]);
if (val & ~0xff)
return -1;
*sha1++ = val;
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment