From: Junio C Hamano Date: Wed, 3 Sep 2008 00:05:44 +0000 (-0700) Subject: Merge branch 'np/maint-safer-pack' into np/pack X-Git-Tag: v1.6.1-rc1~229^2~3 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/59d94bc9c851f9f4086a857bc6277feca6a48824?ds=inline;hp=-c Merge branch 'np/maint-safer-pack' into np/pack * np/maint-safer-pack: fixup_pack_header_footer(): use nicely aligned buffer sizes index-pack: use fixup_pack_header_footer()'s validation mode pack-objects: use fixup_pack_header_footer()'s validation mode improve reliability of fixup_pack_header_footer() pack-objects: improve returned information from write_one() --- 59d94bc9c851f9f4086a857bc6277feca6a48824 diff --combined builtin-pack-objects.c index ef3befe57b,a02c673fb7..ba2cf00f5e --- a/builtin-pack-objects.c +++ b/builtin-pack-objects.c @@@ -410,25 -410,22 +410,22 @@@ static unsigned long write_object(struc return hdrlen + datalen; } - static off_t write_one(struct sha1file *f, + static int write_one(struct sha1file *f, struct object_entry *e, - off_t offset) + off_t *offset) { unsigned long size; /* offset is non zero if object is written already. */ if (e->idx.offset || e->preferred_base) - return offset; + return 1; /* if we are deltified, write out base object first. */ - if (e->delta) { - offset = write_one(f, e->delta, offset); - if (!offset) - return 0; - } + if (e->delta && !write_one(f, e->delta, offset)) + return 0; - e->idx.offset = offset; - size = write_object(f, e, offset); + e->idx.offset = *offset; + size = write_object(f, e, *offset); if (!size) { e->idx.offset = 0; return 0; @@@ -436,9 -433,10 +433,10 @@@ written_list[nr_written++] = &e->idx; /* make sure off_t is sufficiently large not to wrap */ - if (offset > offset + size) + if (*offset > *offset + size) die("pack too large for current definition of off_t"); - return offset + size; + *offset += size; + return 1; } /* forward declaration for write_pack_file */ @@@ -448,7 -446,7 +446,7 @@@ static void write_pack_file(void { uint32_t i = 0, j; struct sha1file *f; - off_t offset, offset_one, last_obj_offset = 0; + off_t offset; struct pack_header hdr; uint32_t nr_remaining = nr_result; time_t last_mtime = 0; @@@ -480,11 -478,8 +478,8 @@@ offset = sizeof(hdr); nr_written = 0; for (; i < nr_objects; i++) { - last_obj_offset = offset; - offset_one = write_one(f, objects + i, offset); - if (!offset_one) + if (!write_one(f, objects + i, &offset)) break; - offset = offset_one; display_progress(progress_state, written); } @@@ -497,8 -492,9 +492,9 @@@ } else if (nr_written == nr_remaining) { sha1close(f, sha1, CSUM_FSYNC); } else { - int fd = sha1close(f, NULL, 0); - fixup_pack_header_footer(fd, sha1, pack_tmp_name, nr_written); + int fd = sha1close(f, sha1, 0); + fixup_pack_header_footer(fd, sha1, pack_tmp_name, + nr_written, sha1, offset); close(fd); } @@@ -1095,12 -1091,9 +1091,12 @@@ static void check_object(struct object_ } entry->type = sha1_object_info(entry->idx.sha1, &entry->size); - if (entry->type < 0) - die("unable to get type of object %s", - sha1_to_hex(entry->idx.sha1)); + /* + * The error condition is checked in prepare_pack(). This is + * to permit a missing preferred base object to be ignored + * as a preferred base. Doing so can result in a larger + * pack file, but the transfer will still take place. + */ } static int pack_offset_sort(const void *_a, const void *_b) @@@ -1724,12 -1717,8 +1720,12 @@@ static void prepare_pack(int window, in if (entry->no_try_delta) continue; - if (!entry->preferred_base) + if (!entry->preferred_base) { nr_deltas++; + if (entry->type < 0) + die("unable to get type of object %s", + sha1_to_hex(entry->idx.sha1)); + } delta_list[n++] = entry; }