fix multiple issues in index-pack
authorNicolas Pitre <nico@cam.org>
Mon, 20 Oct 2008 20:46:19 +0000 (16:46 -0400)
committerJunio C Hamano <gitster@pobox.com>
Mon, 20 Oct 2008 22:16:23 +0000 (15:16 -0700)
Since commit 9441b61dc5, two issues affected correct behavior of
index-pack:

 1) The real_type of a delta object is the 'real_type' of its base, not
    the 'type' which can be a "delta type".  Consequence of this is a
    corrupted pack index file which only needs to be recreated with a
    good index-pack command ('git verify-pack' will flag those).

 2) The code sequence:

        result->data = patch_delta(get_base_data(base), base->obj->size,
                                   delta_data, delta_size, &result->size);

    has two issues of its own since base->obj->size should instead be
    base->size as we want the size of the actual object data and not
    the size of the delta object it is represented by.  Except that
    simply replacing base->obj->size with base->size won't make the
    code more correct as the C language doesn't enforce a particular
    ordering for the evaluation of needed arguments for a function call,
    hence base->size could be pushed on the stack before get_base_data()
    which initializes base->size is called.

Signed-off-by: Nicolas Pitre <nico@cam.org>
Tested-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
index-pack.c

index 9def641..f109a00 100644 (file)
@@ -514,15 +514,14 @@ static void *get_base_data(struct base_data *c)
 static void resolve_delta(struct object_entry *delta_obj,
                          struct base_data *base, struct base_data *result)
 {
-       void *delta_data;
-       unsigned long delta_size;
+       void *base_data, *delta_data;
 
-       delta_obj->real_type = base->obj->type;
+       delta_obj->real_type = base->obj->real_type;
        delta_data = get_data_from_pack(delta_obj);
-       delta_size = delta_obj->size;
+       base_data = get_base_data(base);
        result->obj = delta_obj;
-       result->data = patch_delta(get_base_data(base), base->obj->size,
-                                  delta_data, delta_size, &result->size);
+       result->data = patch_delta(base_data, base->size,
+                                  delta_data, delta_obj->size, &result->size);
        free(delta_data);
        if (!result->data)
                bad_object(delta_obj->idx.offset, "failed to apply delta");