906
return b->pack_int_id - a->pack_int_id;
907
}
908
909
+/*
910
+ * Return whether the pack index contains an entry with both "oid" and
911
+ * "offset". A pack index may contain duplicate OIDs, so an arbitrary
912
+ * OID lookup is not enough to validate a particular offset.
913
+ *
914
+ * Do not use offset_to_pack_pos() here: it may consult an optional '.rev'
915
+ * file, which is verified separately, or build an in-memory reverse index
916
+ * that remains attached to the pack. Verify the MIDX directly against its
917
+ * source pack index instead.
918
+ */
919
+static int pack_index_has_oid_at_offset(struct packed_git *p,
920
+ const struct object_id *oid,
921
+ off_t offset)
922
+{
923
+ struct object_id candidate;
924
+ uint32_t pos, i;
925
+
926
+ if (!bsearch_pack(oid, p, &pos))
927
+ return 0;
928
+
929
+ if (nth_packed_object_offset(p, pos) == offset)
930
+ return 1;
931
+
932
+ for (i = pos; i > 0; i--) {
933
+ if (nth_packed_object_id(&candidate, p, i - 1) ||
934
+ !oideq(&candidate, oid))
935
+ break;
936
+ if (nth_packed_object_offset(p, i - 1) == offset)
937
+ return 1;
938
+ }
939
+
940
+ for (i = pos + 1; i < p->num_objects; i++) {
941
+ if (nth_packed_object_id(&candidate, p, i) ||
942
+ !oideq(&candidate, oid))
943
+ break;
944
+ if (nth_packed_object_offset(p, i) == offset)
945
+ return 1;
946
+ }
947
+
948
+ return 0;
949
+}
950
+
951
/*
952
* Limit calls to display_progress() for performance reasons.
953
* The interval here was arbitrarily chosen.
1057
for (i = 0; i < m->num_objects + m->num_objects_in_base; i++) {
1058
struct object_id oid;
1059
struct pack_entry e;
1018
- off_t m_offset, p_offset;
1060
1061
if (i > 0 && pairs[i-1].pack_int_id != pairs[i].pack_int_id &&
1062
nth_midxed_pack(m, pairs[i-1].pack_int_id)) {
1081
break;
1082
}
1083
1043
- m_offset = e.offset;
1044
- p_offset = find_pack_entry_one(&oid, e.p);
1045
-
1046
- if (m_offset != p_offset)
1047
- midx_report(_("incorrect object offset for oid[%d] = %s: %"PRIx64" != %"PRIx64),
1048
- pairs[i].pos, oid_to_hex(&oid), m_offset, p_offset);
1084
+ /*
1085
+ * Check that the exact offset recorded in the MIDX
1086
+ * belongs to this OID. A pack index may contain
1087
+ * duplicate OIDs, in which case an arbitrary OID lookup
1088
+ * can return a different, equally valid copy than the
1089
+ * one selected by the MIDX writer.
1090
+ */
1091
+ if (!pack_index_has_oid_at_offset(e.p, &oid, e.offset))
1092
+ midx_report(_("incorrect object offset for oid[%d] = %s: %"PRIx64),
1093
+ pairs[i].pos, oid_to_hex(&oid), e.offset);
1094
1095
midx_display_sparse_progress(progress, i + 1);
1096
}