{"thread":{"id":"7087","subject":"[PATCH 2/3] unpack_sha1_file(): detect corrupt loose object files.","startedAt":"2007-03-05T08:21:37Z","lastAt":"2007-03-05T08:21:37Z","messageCount":1,"participants":["Junio C Hamano"],"isPatch":true,"patchVersion":1,"patchTotal":3},"messages":[{"id":"36292","messageId":"7v1wk42j8u.fsf@assigned-by-dhcp.cox.net","threadId":"7087","inReplyTo":null,"subject":"[PATCH 2/3] unpack_sha1_file(): detect corrupt loose object files.","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2007-03-05T08:21:37Z","receivedAt":"2007-03-05T08:21:37Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"We did not detect broken loose object files, either when\nunderlying inflate() signalled the breakage, nor inflate()\nfinished and we had garbage trailing at the end.  We do better\nnow.\n\nWe also make unpack_sha1_file() a static function to\nsha1_file.c, since it is not used by anybody outside.\n\nSigned-off-by: Junio C Hamano <junkio@cox.net>\n---\n cache.h     |    1 -\n sha1_file.c |   27 +++++++++++++++++++--------\n 2 files changed, 19 insertions(+), 9 deletions(-)\n\ndiff --git a/cache.h b/cache.h\nindex c291163..4b5a754 100644\n--- a/cache.h\n+++ b/cache.h\n@@ -281,7 +281,6 @@ char *enter_repo(char *path, int strict);\n \n /* Read and unpack a sha1 file into memory, write memory to a sha1 file */\n extern int sha1_object_info(const unsigned char *, unsigned long *);\n-extern void * unpack_sha1_file(void *map, unsigned long mapsize, enum object_type *type, unsigned long *size);\n extern void * read_sha1_file(const unsigned char *sha1, enum object_type *type, unsigned long *size);\n extern int hash_sha1_file(void *buf, unsigned long len, const char *type, unsigned char *sha1);\n extern int write_sha1_file(void *buf, unsigned long len, const char *type, unsigned char *return_sha1);\ndiff --git a/sha1_file.c b/sha1_file.c\nindex 6d0a72e..ac6b5e0 100644\n--- a/sha1_file.c\n+++ b/sha1_file.c\n@@ -956,11 +956,12 @@ static int unpack_sha1_header(z_stream *stream, unsigned char *map, unsigned lon\n \treturn 0;\n }\n \n-static void *unpack_sha1_rest(z_stream *stream, void *buffer, unsigned long size)\n+static void *unpack_sha1_rest(z_stream *stream, void *buffer, unsigned long size, const unsigned char *sha1)\n {\n \tint bytes = strlen(buffer) + 1;\n \tunsigned char *buf = xmalloc(1+size);\n \tunsigned long n;\n+\tint status = Z_OK;\n \n \tn = stream->total_out - bytes;\n \tif (n > size)\n@@ -970,12 +971,22 @@ static void *unpack_sha1_rest(z_stream *stream, void *buffer, unsigned long size\n \tif (bytes < size) {\n \t\tstream->next_out = buf + bytes;\n \t\tstream->avail_out = size - bytes;\n-\t\twhile (inflate(stream, Z_FINISH) == Z_OK)\n-\t\t\t/* nothing */;\n+\t\twhile (status == Z_OK)\n+\t\t\tstatus = inflate(stream, Z_FINISH);\n \t}\n \tbuf[size] = 0;\n-\tinflateEnd(stream);\n-\treturn buf;\n+\tif ((status == Z_OK || status == Z_STREAM_END) && !stream->avail_in) {\n+\t\tinflateEnd(stream);\n+\t\treturn buf;\n+\t}\n+\n+\tif (status < 0)\n+\t\terror(\"corrupt loose object '%s'\", sha1_to_hex(sha1));\n+\telse if (stream->avail_in)\n+\t\terror(\"garbage at end of loose object '%s'\",\n+\t\t      sha1_to_hex(sha1));\n+\tfree(buf);\n+\treturn NULL;\n }\n \n /*\n@@ -1029,7 +1040,7 @@ static int parse_sha1_header(const char *hdr, unsigned long *sizep)\n \treturn *hdr ? -1 : type_from_string(type);\n }\n \n-void * unpack_sha1_file(void *map, unsigned long mapsize, enum object_type *type, unsigned long *size)\n+static void *unpack_sha1_file(void *map, unsigned long mapsize, enum object_type *type, unsigned long *size, const unsigned char *sha1)\n {\n \tint ret;\n \tz_stream stream;\n@@ -1039,7 +1050,7 @@ void * unpack_sha1_file(void *map, unsigned long mapsize, enum object_type *type\n \tif (ret < Z_OK || (*type = parse_sha1_header(hdr, size)) < 0)\n \t\treturn NULL;\n \n-\treturn unpack_sha1_rest(&stream, hdr, *size);\n+\treturn unpack_sha1_rest(&stream, hdr, *size, sha1);\n }\n \n static unsigned long get_delta_base(struct packed_git *p,\n@@ -1555,7 +1566,7 @@ void *read_sha1_file(const unsigned char *sha1, enum object_type *type,\n \t\treturn buf;\n \tmap = map_sha1_file(sha1, &mapsize);\n \tif (map) {\n-\t\tbuf = unpack_sha1_file(map, mapsize, type, size);\n+\t\tbuf = unpack_sha1_file(map, mapsize, type, size, sha1);\n \t\tmunmap(map, mapsize);\n \t\treturn buf;\n \t}\n-- \n1.5.0.3.855.ga3b2\n"}]}