From 8d8a4ea5530ef9c738341887a7dcece4abd7dcbe Mon Sep 17 00:00:00 2001 From: "Shawn O. Pearce" Date: Sat, 23 Dec 2006 02:34:18 -0500 Subject: [PATCH] Document why header parsing won't exceed a window. When we parse the object header or the delta base reference we don't bother to loop over use_pack() calls. The reason we don't need to bother with calling use_pack for each byte accessed is that use_pack will always promise us at least 20 bytes (really the hash size) after the offset. This promise from use_pack simplifies a lot of code in the header parsing logic, as well as helps out the zlib library by ensuring there's always some data for it to consume during an inflate call. Signed-off-by: Shawn O. Pearce Signed-off-by: Junio C Hamano --- sha1_file.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/sha1_file.c b/sha1_file.c index c304522519..3466969344 100644 --- a/sha1_file.c +++ b/sha1_file.c @@ -903,10 +903,12 @@ static unsigned long get_delta_base(struct packed_git *p, unsigned char *base_info = use_pack(p, w_curs, offset, NULL); unsigned long base_offset; - /* there must be at least 20 bytes left regardless of delta type */ - if (p->pack_size <= offset + 20) - die("truncated pack file"); - + /* use_pack() assured us we have [base_info, base_info + 20) + * as a range that we can look at without walking off the + * end of the mapped window. Its actually the hash size + * that is assured. An OFS_DELTA longer than the hash size + * is stupid, as then a REF_DELTA would be smaller to store. + */ if (kind == OBJ_OFS_DELTA) { unsigned used = 0; unsigned char c = base_info[used++]; @@ -1009,6 +1011,12 @@ static unsigned long unpack_object_header(struct packed_git *p, unsigned int left; unsigned long used; + /* use_pack() assures us we have [base, base + 20) available + * as a range that we can look at at. (Its actually the hash + * size that is assurred.) With our object header encoding + * the maximum deflated object size is 2^137, which is just + * insane, so we know won't exceed what we have been given. + */ base = use_pack(p, w_curs, offset, &left); used = unpack_object_header_gently(base, left, type, sizep); if (!used) -- 2.11.4.GIT