3 #include "pack-revindex.h"
8 const unsigned char *sha1
;
12 static int compare_entries(const void *e1
, const void *e2
)
14 const struct idx_entry
*entry1
= e1
;
15 const struct idx_entry
*entry2
= e2
;
16 if (entry1
->offset
< entry2
->offset
)
18 if (entry1
->offset
> entry2
->offset
)
23 int check_pack_crc(struct packed_git
*p
, struct pack_window
**w_curs
,
24 off_t offset
, off_t len
, unsigned int nr
)
26 const uint32_t *index_crc
;
27 uint32_t data_crc
= crc32(0, Z_NULL
, 0);
31 void *data
= use_pack(p
, w_curs
, offset
, &avail
);
34 data_crc
= crc32(data_crc
, data
, avail
);
39 index_crc
= p
->index_data
;
40 index_crc
+= 2 + 256 + p
->num_objects
* (20/4) + nr
;
42 return data_crc
!= ntohl(*index_crc
);
45 static int verify_packfile(struct packed_git
*p
,
46 struct pack_window
**w_curs
)
48 off_t index_size
= p
->index_size
;
49 const unsigned char *index_base
= p
->index_data
;
51 unsigned char sha1
[20], *pack_sig
;
52 off_t offset
= 0, pack_sig_ofs
= 0;
53 uint32_t nr_objects
, i
;
55 struct idx_entry
*entries
;
57 /* Note that the pack header checks are actually performed by
58 * use_pack when it first opens the pack file. If anything
59 * goes wrong during those checks then the call will die out
65 unsigned int remaining
;
66 unsigned char *in
= use_pack(p
, w_curs
, offset
, &remaining
);
69 pack_sig_ofs
= p
->pack_size
- 20;
70 if (offset
> pack_sig_ofs
)
71 remaining
-= (unsigned int)(offset
- pack_sig_ofs
);
72 git_SHA1_Update(&ctx
, in
, remaining
);
73 } while (offset
< pack_sig_ofs
);
74 git_SHA1_Final(sha1
, &ctx
);
75 pack_sig
= use_pack(p
, w_curs
, pack_sig_ofs
, NULL
);
76 if (hashcmp(sha1
, pack_sig
))
77 err
= error("%s SHA1 checksum mismatch",
79 if (hashcmp(index_base
+ index_size
- 40, pack_sig
))
80 err
= error("%s SHA1 does not match its inddex",
84 /* Make sure everything reachable from idx is valid. Since we
85 * have verified that nr_objects matches between idx and pack,
86 * we do not do scan-streaming check on the pack file.
88 nr_objects
= p
->num_objects
;
89 entries
= xmalloc((nr_objects
+ 1) * sizeof(*entries
));
90 entries
[nr_objects
].offset
= pack_sig_ofs
;
91 /* first sort entries by pack offset, since unpacking them is more efficient that way */
92 for (i
= 0; i
< nr_objects
; i
++) {
93 entries
[i
].sha1
= nth_packed_object_sha1(p
, i
);
95 die("internal error pack-check nth-packed-object");
96 entries
[i
].offset
= nth_packed_object_offset(p
, i
);
99 qsort(entries
, nr_objects
, sizeof(*entries
), compare_entries
);
101 for (i
= 0; i
< nr_objects
; i
++) {
103 enum object_type type
;
106 if (p
->index_version
> 1) {
107 off_t offset
= entries
[i
].offset
;
108 off_t len
= entries
[i
+1].offset
- offset
;
109 unsigned int nr
= entries
[i
].nr
;
110 if (check_pack_crc(p
, w_curs
, offset
, len
, nr
))
111 err
= error("index CRC mismatch for object %s "
112 "from %s at offset %"PRIuMAX
"",
113 sha1_to_hex(entries
[i
].sha1
),
114 p
->pack_name
, (uintmax_t)offset
);
116 data
= unpack_entry(p
, entries
[i
].offset
, &type
, &size
);
118 err
= error("cannot unpack %s from %s at offset %"PRIuMAX
"",
119 sha1_to_hex(entries
[i
].sha1
), p
->pack_name
,
120 (uintmax_t)entries
[i
].offset
);
123 if (check_sha1_signature(entries
[i
].sha1
, data
, size
, typename(type
))) {
124 err
= error("packed %s from %s is corrupt",
125 sha1_to_hex(entries
[i
].sha1
), p
->pack_name
);
136 int verify_pack(struct packed_git
*p
)
139 const unsigned char *index_base
;
141 unsigned char sha1
[20];
143 struct pack_window
*w_curs
= NULL
;
145 if (open_pack_index(p
))
146 return error("packfile %s index not opened", p
->pack_name
);
147 index_size
= p
->index_size
;
148 index_base
= p
->index_data
;
150 /* Verify SHA1 sum of the index file */
152 git_SHA1_Update(&ctx
, index_base
, (unsigned int)(index_size
- 20));
153 git_SHA1_Final(sha1
, &ctx
);
154 if (hashcmp(sha1
, index_base
+ index_size
- 20))
155 err
= error("Packfile index for %s SHA1 mismatch",
158 /* Verify pack file */
159 err
|= verify_packfile(p
, &w_curs
);