~ubuntu-branches/ubuntu/intrepid/git-core/intrepid-security

« back to all changes in this revision

Viewing changes to index-pack.c

  • Committer: Package Import Robot
  • Author(s): Gerrit Pape
  • Date: 2007-10-04 08:27:01 UTC
  • mfrom: (1.1.23)
  • Revision ID: package-import@ubuntu.com-20071004082701-rsd058ontoqz4i30
Tags: 1:1.5.3.4-1
new upstream point release (closes: #445188).

Show diffs side-by-side

added added

removed removed

Lines of Context:
13
13
 
14
14
struct object_entry
15
15
{
16
 
        off_t offset;
 
16
        struct pack_idx_entry idx;
17
17
        unsigned long size;
18
18
        unsigned int hdr_size;
19
 
        uint32_t crc32;
20
19
        enum object_type type;
21
20
        enum object_type real_type;
22
 
        unsigned char sha1[20];
23
21
};
24
22
 
25
23
union delta_base {
116
114
                        static char tmpfile[PATH_MAX];
117
115
                        snprintf(tmpfile, sizeof(tmpfile),
118
116
                                 "%s/tmp_pack_XXXXXX", get_object_directory());
119
 
                        output_fd = mkstemp(tmpfile);
 
117
                        output_fd = xmkstemp(tmpfile);
120
118
                        pack_name = xstrdup(tmpfile);
121
119
                } else
122
120
                        output_fd = open(pack_name, O_CREAT|O_EXCL|O_RDWR, 0600);
197
195
        unsigned shift;
198
196
        void *data;
199
197
 
200
 
        obj->offset = consumed_bytes;
 
198
        obj->idx.offset = consumed_bytes;
201
199
        input_crc32 = crc32(0, Z_NULL, 0);
202
200
 
203
201
        p = fill(1);
229
227
                while (c & 128) {
230
228
                        base_offset += 1;
231
229
                        if (!base_offset || MSB(base_offset, 7))
232
 
                                bad_object(obj->offset, "offset value overflow for delta base object");
 
230
                                bad_object(obj->idx.offset, "offset value overflow for delta base object");
233
231
                        p = fill(1);
234
232
                        c = *p;
235
233
                        use(1);
236
234
                        base_offset = (base_offset << 7) + (c & 127);
237
235
                }
238
 
                delta_base->offset = obj->offset - base_offset;
239
 
                if (delta_base->offset >= obj->offset)
240
 
                        bad_object(obj->offset, "delta base offset is out of bound");
 
236
                delta_base->offset = obj->idx.offset - base_offset;
 
237
                if (delta_base->offset >= obj->idx.offset)
 
238
                        bad_object(obj->idx.offset, "delta base offset is out of bound");
241
239
                break;
242
240
        case OBJ_COMMIT:
243
241
        case OBJ_TREE:
245
243
        case OBJ_TAG:
246
244
                break;
247
245
        default:
248
 
                bad_object(obj->offset, "unknown object type %d", obj->type);
 
246
                bad_object(obj->idx.offset, "unknown object type %d", obj->type);
249
247
        }
250
 
        obj->hdr_size = consumed_bytes - obj->offset;
 
248
        obj->hdr_size = consumed_bytes - obj->idx.offset;
251
249
 
252
 
        data = unpack_entry_data(obj->offset, obj->size);
253
 
        obj->crc32 = input_crc32;
 
250
        data = unpack_entry_data(obj->idx.offset, obj->size);
 
251
        obj->idx.crc32 = input_crc32;
254
252
        return data;
255
253
}
256
254
 
257
255
static void *get_data_from_pack(struct object_entry *obj)
258
256
{
259
 
        unsigned long from = obj[0].offset + obj[0].hdr_size;
260
 
        unsigned long len = obj[1].offset - from;
 
257
        unsigned long from = obj[0].idx.offset + obj[0].hdr_size;
 
258
        unsigned long len = obj[1].idx.offset - from;
261
259
        unsigned long rdy = 0;
262
260
        unsigned char *src, *data;
263
261
        z_stream stream;
360
358
                             &result_size);
361
359
        free(delta_data);
362
360
        if (!result)
363
 
                bad_object(delta_obj->offset, "failed to apply delta");
364
 
        sha1_object(result, result_size, type, delta_obj->sha1);
 
361
                bad_object(delta_obj->idx.offset, "failed to apply delta");
 
362
        sha1_object(result, result_size, type, delta_obj->idx.sha1);
365
363
        nr_resolved_deltas++;
366
364
 
367
 
        hashcpy(delta_base.sha1, delta_obj->sha1);
 
365
        hashcpy(delta_base.sha1, delta_obj->idx.sha1);
368
366
        if (!find_delta_children(&delta_base, &first, &last)) {
369
367
                for (j = first; j <= last; j++) {
370
368
                        struct object_entry *child = objects + deltas[j].obj_no;
374
372
        }
375
373
 
376
374
        memset(&delta_base, 0, sizeof(delta_base));
377
 
        delta_base.offset = delta_obj->offset;
 
375
        delta_base.offset = delta_obj->idx.offset;
378
376
        if (!find_delta_children(&delta_base, &first, &last)) {
379
377
                for (j = first; j <= last; j++) {
380
378
                        struct object_entry *child = objects + deltas[j].obj_no;
418
416
                        delta->obj_no = i;
419
417
                        delta++;
420
418
                } else
421
 
                        sha1_object(data, obj->size, obj->type, obj->sha1);
 
419
                        sha1_object(data, obj->size, obj->type, obj->idx.sha1);
422
420
                free(data);
423
421
                if (verbose)
424
422
                        display_progress(&progress, i+1);
425
423
        }
426
 
        objects[i].offset = consumed_bytes;
 
424
        objects[i].idx.offset = consumed_bytes;
427
425
        if (verbose)
428
426
                stop_progress(&progress);
429
427
 
465
463
 
466
464
                if (obj->type == OBJ_REF_DELTA || obj->type == OBJ_OFS_DELTA)
467
465
                        continue;
468
 
                hashcpy(base.sha1, obj->sha1);
 
466
                hashcpy(base.sha1, obj->idx.sha1);
469
467
                ref = !find_delta_children(&base, &ref_first, &ref_last);
470
468
                memset(&base, 0, sizeof(base));
471
 
                base.offset = obj->offset;
 
469
                base.offset = obj->idx.offset;
472
470
                ofs = !find_delta_children(&base, &ofs_first, &ofs_last);
473
471
                if (!ref && !ofs)
474
472
                        continue;
535
533
        }
536
534
        header[n++] = c;
537
535
        write_or_die(output_fd, header, n);
538
 
        obj[0].crc32 = crc32(0, Z_NULL, 0);
539
 
        obj[0].crc32 = crc32(obj[0].crc32, header, n);
540
 
        obj[1].offset = obj[0].offset + n;
541
 
        obj[1].offset += write_compressed(output_fd, buf, size, &obj[0].crc32);
542
 
        hashcpy(obj->sha1, sha1);
 
536
        obj[0].idx.crc32 = crc32(0, Z_NULL, 0);
 
537
        obj[0].idx.crc32 = crc32(obj[0].idx.crc32, header, n);
 
538
        obj[1].idx.offset = obj[0].idx.offset + n;
 
539
        obj[1].idx.offset += write_compressed(output_fd, buf, size, &obj[0].idx.crc32);
 
540
        hashcpy(obj->idx.sha1, sha1);
543
541
}
544
542
 
545
543
static int delta_pos_compare(const void *_a, const void *_b)
602
600
        free(sorted_by_pos);
603
601
}
604
602
 
605
 
static uint32_t index_default_version = 1;
606
 
static uint32_t index_off32_limit = 0x7fffffff;
607
 
 
608
 
static int sha1_compare(const void *_a, const void *_b)
609
 
{
610
 
        struct object_entry *a = *(struct object_entry **)_a;
611
 
        struct object_entry *b = *(struct object_entry **)_b;
612
 
        return hashcmp(a->sha1, b->sha1);
613
 
}
614
 
 
615
 
/*
616
 
 * On entry *sha1 contains the pack content SHA1 hash, on exit it is
617
 
 * the SHA1 hash of sorted object names.
618
 
 */
619
 
static const char *write_index_file(const char *index_name, unsigned char *sha1)
620
 
{
621
 
        struct sha1file *f;
622
 
        struct object_entry **sorted_by_sha, **list, **last;
623
 
        uint32_t array[256];
624
 
        int i, fd;
625
 
        SHA_CTX ctx;
626
 
        uint32_t index_version;
627
 
 
628
 
        if (nr_objects) {
629
 
                sorted_by_sha =
630
 
                        xcalloc(nr_objects, sizeof(struct object_entry *));
631
 
                list = sorted_by_sha;
632
 
                last = sorted_by_sha + nr_objects;
633
 
                for (i = 0; i < nr_objects; ++i)
634
 
                        sorted_by_sha[i] = &objects[i];
635
 
                qsort(sorted_by_sha, nr_objects, sizeof(sorted_by_sha[0]),
636
 
                      sha1_compare);
637
 
        }
638
 
        else
639
 
                sorted_by_sha = list = last = NULL;
640
 
 
641
 
        if (!index_name) {
642
 
                static char tmpfile[PATH_MAX];
643
 
                snprintf(tmpfile, sizeof(tmpfile),
644
 
                         "%s/tmp_idx_XXXXXX", get_object_directory());
645
 
                fd = mkstemp(tmpfile);
646
 
                index_name = xstrdup(tmpfile);
647
 
        } else {
648
 
                unlink(index_name);
649
 
                fd = open(index_name, O_CREAT|O_EXCL|O_WRONLY, 0600);
650
 
        }
651
 
        if (fd < 0)
652
 
                die("unable to create %s: %s", index_name, strerror(errno));
653
 
        f = sha1fd(fd, index_name);
654
 
 
655
 
        /* if last object's offset is >= 2^31 we should use index V2 */
656
 
        index_version = (objects[nr_objects-1].offset >> 31) ? 2 : index_default_version;
657
 
 
658
 
        /* index versions 2 and above need a header */
659
 
        if (index_version >= 2) {
660
 
                struct pack_idx_header hdr;
661
 
                hdr.idx_signature = htonl(PACK_IDX_SIGNATURE);
662
 
                hdr.idx_version = htonl(index_version);
663
 
                sha1write(f, &hdr, sizeof(hdr));
664
 
        }
665
 
 
666
 
        /*
667
 
         * Write the first-level table (the list is sorted,
668
 
         * but we use a 256-entry lookup to be able to avoid
669
 
         * having to do eight extra binary search iterations).
670
 
         */
671
 
        for (i = 0; i < 256; i++) {
672
 
                struct object_entry **next = list;
673
 
                while (next < last) {
674
 
                        struct object_entry *obj = *next;
675
 
                        if (obj->sha1[0] != i)
676
 
                                break;
677
 
                        next++;
678
 
                }
679
 
                array[i] = htonl(next - sorted_by_sha);
680
 
                list = next;
681
 
        }
682
 
        sha1write(f, array, 256 * 4);
683
 
 
684
 
        /* compute the SHA1 hash of sorted object names. */
685
 
        SHA1_Init(&ctx);
686
 
 
687
 
        /*
688
 
         * Write the actual SHA1 entries..
689
 
         */
690
 
        list = sorted_by_sha;
691
 
        for (i = 0; i < nr_objects; i++) {
692
 
                struct object_entry *obj = *list++;
693
 
                if (index_version < 2) {
694
 
                        uint32_t offset = htonl(obj->offset);
695
 
                        sha1write(f, &offset, 4);
696
 
                }
697
 
                sha1write(f, obj->sha1, 20);
698
 
                SHA1_Update(&ctx, obj->sha1, 20);
699
 
        }
700
 
 
701
 
        if (index_version >= 2) {
702
 
                unsigned int nr_large_offset = 0;
703
 
 
704
 
                /* write the crc32 table */
705
 
                list = sorted_by_sha;
706
 
                for (i = 0; i < nr_objects; i++) {
707
 
                        struct object_entry *obj = *list++;
708
 
                        uint32_t crc32_val = htonl(obj->crc32);
709
 
                        sha1write(f, &crc32_val, 4);
710
 
                }
711
 
 
712
 
                /* write the 32-bit offset table */
713
 
                list = sorted_by_sha;
714
 
                for (i = 0; i < nr_objects; i++) {
715
 
                        struct object_entry *obj = *list++;
716
 
                        uint32_t offset = (obj->offset <= index_off32_limit) ?
717
 
                                obj->offset : (0x80000000 | nr_large_offset++);
718
 
                        offset = htonl(offset);
719
 
                        sha1write(f, &offset, 4);
720
 
                }
721
 
 
722
 
                /* write the large offset table */
723
 
                list = sorted_by_sha;
724
 
                while (nr_large_offset) {
725
 
                        struct object_entry *obj = *list++;
726
 
                        uint64_t offset = obj->offset;
727
 
                        if (offset > index_off32_limit) {
728
 
                                uint32_t split[2];
729
 
                                split[0]        = htonl(offset >> 32);
730
 
                                split[1] = htonl(offset & 0xffffffff);
731
 
                                sha1write(f, split, 8);
732
 
                                nr_large_offset--;
733
 
                        }
734
 
                }
735
 
        }
736
 
 
737
 
        sha1write(f, sha1, 20);
738
 
        sha1close(f, NULL, 1);
739
 
        free(sorted_by_sha);
740
 
        SHA1_Final(sha1, &ctx);
741
 
        return index_name;
742
 
}
743
 
 
744
603
static void final(const char *final_pack_name, const char *curr_pack_name,
745
604
                  const char *final_index_name, const char *curr_index_name,
746
605
                  const char *keep_name, const char *keep_msg,
775
634
                                write_or_die(keep_fd, keep_msg, keep_msg_len);
776
635
                                write_or_die(keep_fd, "\n", 1);
777
636
                        }
778
 
                        close(keep_fd);
 
637
                        if (close(keep_fd) != 0)
 
638
                                die("cannot write keep file");
779
639
                        report = "keep";
780
640
                }
781
641
        }
830
690
        const char *curr_index, *index_name = NULL;
831
691
        const char *keep_name = NULL, *keep_msg = NULL;
832
692
        char *index_name_buf = NULL, *keep_name_buf = NULL;
 
693
        struct pack_idx_entry **idx_objects;
833
694
        unsigned char sha1[20];
834
695
 
835
696
        for (i = 1; i < argc; i++) {
865
726
                                index_name = argv[++i];
866
727
                        } else if (!prefixcmp(arg, "--index-version=")) {
867
728
                                char *c;
868
 
                                index_default_version = strtoul(arg + 16, &c, 10);
869
 
                                if (index_default_version > 2)
 
729
                                pack_idx_default_version = strtoul(arg + 16, &c, 10);
 
730
                                if (pack_idx_default_version > 2)
870
731
                                        die("bad %s", arg);
871
732
                                if (*c == ',')
872
 
                                        index_off32_limit = strtoul(c+1, &c, 0);
873
 
                                if (*c || index_off32_limit & 0x80000000)
 
733
                                        pack_idx_off32_limit = strtoul(c+1, &c, 0);
 
734
                                if (*c || pack_idx_off32_limit & 0x80000000)
874
735
                                        die("bad %s", arg);
875
736
                        } else
876
737
                                usage(index_pack_usage);
940
801
                            nr_deltas - nr_resolved_deltas);
941
802
        }
942
803
        free(deltas);
943
 
        curr_index = write_index_file(index_name, sha1);
 
804
 
 
805
        idx_objects = xmalloc((nr_objects) * sizeof(struct pack_idx_entry *));
 
806
        for (i = 0; i < nr_objects; i++)
 
807
                idx_objects[i] = &objects[i].idx;
 
808
        curr_index = write_idx_file(index_name, idx_objects, nr_objects, sha1);
 
809
        free(idx_objects);
 
810
 
944
811
        final(pack_name, curr_pack,
945
812
                index_name, curr_index,
946
813
                keep_name, keep_msg,