verify-pack: check packed object CRC when using index version 2
To do so, check_pack_crc() moved from builtin-pack-objects.c to pack-check.c where it is more logical to share. Signed-off-by: Nicolas Pitre <nico@cam.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Nicolas Pitre committed
Jun 24, 2008 at 23:19 UTC
c41a4a9468b0c728e77ec5d97da7bfb63776ac3f
3 files changed
+38
-25
builtin-pack-objects.c
-22
@@ -209,28 +209,6 @@ static int check_pack_inflate(struct packed_git *p,
209
stream.total_in == len) ? 0 : -1;
210
}
211
212
-static int check_pack_crc(struct packed_git *p, struct pack_window **w_curs,
213
- off_t offset, off_t len, unsigned int nr)
214
-{
215
- const uint32_t *index_crc;
216
- uint32_t data_crc = crc32(0, Z_NULL, 0);
217
-
218
- do {
219
- unsigned int avail;
220
- void *data = use_pack(p, w_curs, offset, &avail);
221
- if (avail > len)
222
- avail = len;
223
- data_crc = crc32(data_crc, data, avail);
224
- offset += avail;
225
- len -= avail;
226
- } while (len);
227
-
228
- index_crc = p->index_data;
229
- index_crc += 2 + 256 + p->num_objects * (20/4) + nr;
230
-
231
- return data_crc != ntohl(*index_crc);
232
-}
233
-
212
static void copy_pack_data(struct sha1file *f,
213
struct packed_git *p,
214
struct pack_window **w_curs,
pack-check.c
+37
-2
@@ -4,8 +4,9 @@
4
5
struct idx_entry
6
{
7
- const unsigned char *sha1;
7
off_t offset;
8
+ const unsigned char *sha1;
9
+ unsigned int nr;
10
};
11
12
static int compare_entries(const void *e1, const void *e2)
@@ -19,6 +20,28 @@ static int compare_entries(const void *e1, const void *e2)
20
return 0;
21
}
22
23
+int check_pack_crc(struct packed_git *p, struct pack_window **w_curs,
24
+ off_t offset, off_t len, unsigned int nr)
25
+{
26
+ const uint32_t *index_crc;
27
+ uint32_t data_crc = crc32(0, Z_NULL, 0);
28
+
29
+ do {
30
+ unsigned int avail;
31
+ void *data = use_pack(p, w_curs, offset, &avail);
32
+ if (avail > len)
33
+ avail = len;
34
+ data_crc = crc32(data_crc, data, avail);
35
+ offset += avail;
36
+ len -= avail;
37
+ } while (len);
38
+
39
+ index_crc = p->index_data;
40
+ index_crc += 2 + 256 + p->num_objects * (20/4) + nr;
41
+
42
+ return data_crc != ntohl(*index_crc);
43
+}
44
+
45
static int verify_packfile(struct packed_git *p,
46
struct pack_window **w_curs)
47
{
@@ -61,13 +84,15 @@ static int verify_packfile(struct packed_git *p,
84
* we do not do scan-streaming check on the pack file.
85
*/
86
nr_objects = p->num_objects;
64
- entries = xmalloc(nr_objects * sizeof(*entries));
87
+ entries = xmalloc((nr_objects + 1) * sizeof(*entries));
88
+ entries[nr_objects].offset = pack_sig_ofs;
89
/* first sort entries by pack offset, since unpacking them is more efficient that way */
90
for (i = 0; i < nr_objects; i++) {
91
entries[i].sha1 = nth_packed_object_sha1(p, i);
92
if (!entries[i].sha1)
93
die("internal error pack-check nth-packed-object");
94
entries[i].offset = nth_packed_object_offset(p, i);
95
+ entries[i].nr = i;
96
}
97
qsort(entries, nr_objects, sizeof(*entries), compare_entries);
98
@@ -76,6 +101,16 @@ static int verify_packfile(struct packed_git *p,
101
enum object_type type;
102
unsigned long size;
103
104
+ if (p->index_version > 1) {
105
+ off_t offset = entries[i].offset;
106
+ off_t len = entries[i+1].offset - offset;
107
+ unsigned int nr = entries[i].nr;
108
+ if (check_pack_crc(p, w_curs, offset, len, nr))
109
+ err = error("index CRC mismatch for object %s "
110
+ "from %s at offset %"PRIuMAX"",
111
+ sha1_to_hex(entries[i].sha1),
112
+ p->pack_name, (uintmax_t)offset);
113
+ }
114
data = unpack_entry(p, entries[i].offset, &type, &size);
115
if (!data) {
116
err = error("cannot unpack %s from %s at offset %"PRIuMAX"",
pack.h
+1
-1
@@ -56,7 +56,7 @@ struct pack_idx_entry {
56
};
57
58
extern char *write_idx_file(char *index_name, struct pack_idx_entry **objects, int nr_objects, unsigned char *sha1);
59
-
59
+extern int check_pack_crc(struct packed_git *p, struct pack_window **w_curs, off_t offset, off_t len, unsigned int nr);
60
extern int verify_pack(struct packed_git *);
61
extern void fixup_pack_header_footer(int, unsigned char *, const char *, uint32_t);
62
extern char *index_pack_lockfile(int fd);