A typical diff will not show what's going on and you need to see full
functions. The core code is like this, at the end of of write_one()

        e->idx.offset = *offset;
        size = write_object(f, e, *offset);
        if (!size) {
                e->idx.offset = recursing;
                return WRITE_ONE_BREAK;
        }
        written_list[nr_written++] = &e->idx;

        /* make sure off_t is sufficiently large not to wrap */
        if (signed_add_overflows(*offset, size))
                die("pack too large for current definition of off_t");
        *offset += size;

Here we can see that the in-pack object size is returned by
write_object (or indirectly by write_reuse_object). And it's used to
calculate object offsets, which end up in the pack index file,
generated at the end.

If "size" overflows (on 32-bit sytems, unsigned long is 32-bit while
off_t can be 64-bit), we got wrong offsets and produce incorrect .idx
file, which may make it look like the .pack file is corrupted.

Signed-off-by: Nguyễn Thái Ngọc Duy <pclo...@gmail.com>
Signed-off-by: Junio C Hamano <gits...@pobox.com>
---
 builtin/pack-objects.c | 15 ++++++++-------
 1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/builtin/pack-objects.c b/builtin/pack-objects.c
index a3a98c5..ac7a3a5 100644
--- a/builtin/pack-objects.c
+++ b/builtin/pack-objects.c
@@ -341,8 +341,8 @@ static unsigned long write_no_reuse_object(struct sha1file 
*f, struct object_ent
 }
 
 /* Return 0 if we will bust the pack-size limit */
-static unsigned long write_reuse_object(struct sha1file *f, struct 
object_entry *entry,
-                                       unsigned long limit, int usable_delta)
+static off_t write_reuse_object(struct sha1file *f, struct object_entry *entry,
+                               unsigned long limit, int usable_delta)
 {
        struct packed_git *p = entry->in_pack;
        struct pack_window *w_curs = NULL;
@@ -415,11 +415,12 @@ static unsigned long write_reuse_object(struct sha1file 
*f, struct object_entry
 }
 
 /* Return 0 if we will bust the pack-size limit */
-static unsigned long write_object(struct sha1file *f,
-                                 struct object_entry *entry,
-                                 off_t write_offset)
+static off_t write_object(struct sha1file *f,
+                         struct object_entry *entry,
+                         off_t write_offset)
 {
-       unsigned long limit, len;
+       unsigned long limit;
+       off_t len;
        int usable_delta, to_reuse;
 
        if (!pack_to_stdout)
@@ -491,7 +492,7 @@ static enum write_one_status write_one(struct sha1file *f,
                                       struct object_entry *e,
                                       off_t *offset)
 {
-       unsigned long size;
+       off_t size;
        int recursing;
 
        /*
-- 
2.9.1.564.gb2f7278

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to