summary refs log tree commit diff
path: root/pack-write.c
diff options
context:
space:
mode:
authorJunio C Hamano <gitster@pobox.com>2011-02-25 16:55:26 -0800
committerJunio C Hamano <gitster@pobox.com>2011-02-27 23:29:03 -0800
commit3c9fc074c220d5d1d2173c84cc6ae57d750e2a2c (patch)
tree99a89b4e8eaf51852e90679e553eeb44cf5e7cf6 /pack-write.c
parentfb956c1f44b5c99273eb9e3850717c8b489ff78f (diff)
index-pack --verify: read anomalous offsets from v2 idx file
A pack v2 .idx file usually records offset using 64-bit representation
only when the offset does not fit within 31-bit, but you can handcraft
your .idx file to record smaller offset using 64-bit, storing all zero
in the upper 4-byte.  By inspecting the original idx file when running
index-pack --verify, encode such low offsets that do not need to be in
64-bit but are encoded using 64-bit just like the original idx file so
that we can still validate the pack/idx pair by comparing the idx file
recomputed with the original.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'pack-write.c')
-rw-r--r--pack-write.c18
1 files changed, 17 insertions, 1 deletions
diff --git a/pack-write.c b/pack-write.c
index 92e7eefb40..9cd3bfbb4b 100644
--- a/pack-write.c
+++ b/pack-write.c
@@ -16,9 +16,25 @@ static int sha1_compare(const void *_a, const void *_b)
 	return hashcmp(a->sha1, b->sha1);
 }
 
+static int cmp_uint32(const void *a_, const void *b_)
+{
+	uint32_t a = *((uint32_t *)a_);
+	uint32_t b = *((uint32_t *)b_);
+
+	return (a < b) ? -1 : (a != b);
+}
+
 static int need_large_offset(off_t offset, const struct pack_idx_option *opts)
 {
-	return (offset >> 31) || (opts->off32_limit < offset);
+	uint32_t ofsval;
+
+	if ((offset >> 31) || (opts->off32_limit < offset))
+		return 1;
+	if (!opts->anomaly_nr)
+		return 0;
+	ofsval = offset;
+	return !!bsearch(&ofsval, opts->anomaly, opts->anomaly_nr,
+			 sizeof(ofsval), cmp_uint32);
 }
 
 /*