mirror of
https://github.com/git/git.git
synced 2026-01-11 21:33:13 +09:00
Merge branch 'pw/midx-repack-overflow-fix'
Integer overflow fix around code paths for "git multi-pack-index repack".. * pw/midx-repack-overflow-fix: midx docs: clarify tie breaking midx: avoid negative array index midx repack: avoid potential integer overflow on 64 bit systems midx repack: avoid integer overflow on 32 bit systems
This commit is contained in:
commit
48a25bbbbb
@ -38,10 +38,13 @@ write::
|
||||
+
|
||||
--
|
||||
--preferred-pack=<pack>::
|
||||
Optionally specify the tie-breaking pack used when
|
||||
multiple packs contain the same object. `<pack>` must
|
||||
contain at least one object. If not given, ties are
|
||||
broken in favor of the pack with the lowest mtime.
|
||||
When specified, break ties in favor of this pack when
|
||||
there are additional copies of its objects in other
|
||||
packs. Ties for objects not found in the preferred
|
||||
pack are always resolved in favor of the copy in the
|
||||
pack with the highest mtime. If unspecified, the pack
|
||||
with the lowest mtime is used by default. The
|
||||
preferred pack must have at least one object.
|
||||
|
||||
--[no-]bitmap::
|
||||
Control whether or not a multi-pack bitmap is written.
|
||||
|
||||
@ -668,6 +668,22 @@ static inline int cast_size_t_to_int(size_t a)
|
||||
return (int)a;
|
||||
}
|
||||
|
||||
static inline uint64_t u64_mult(uint64_t a, uint64_t b)
|
||||
{
|
||||
if (unsigned_mult_overflows(a, b))
|
||||
die("uint64_t overflow: %"PRIuMAX" * %"PRIuMAX,
|
||||
(uintmax_t)a, (uintmax_t)b);
|
||||
return a * b;
|
||||
}
|
||||
|
||||
static inline uint64_t u64_add(uint64_t a, uint64_t b)
|
||||
{
|
||||
if (unsigned_add_overflows(a, b))
|
||||
die("uint64_t overflow: %"PRIuMAX" + %"PRIuMAX,
|
||||
(uintmax_t)a, (uintmax_t)b);
|
||||
return a + b;
|
||||
}
|
||||
|
||||
/*
|
||||
* Limit size of IO chunks, because huge chunks only cause pain. OS X
|
||||
* 64-bit is buggy, returning EINVAL if len >= INT_MAX; and even in
|
||||
|
||||
22
midx-write.c
22
midx-write.c
@ -1566,7 +1566,7 @@ int expire_midx_packs(struct repository *r, const char *object_dir, unsigned fla
|
||||
_("Counting referenced objects"),
|
||||
m->num_objects);
|
||||
for (i = 0; i < m->num_objects; i++) {
|
||||
int pack_int_id = nth_midxed_pack_int_id(m, i);
|
||||
uint32_t pack_int_id = nth_midxed_pack_int_id(m, i);
|
||||
count[pack_int_id]++;
|
||||
display_progress(progress, i + 1);
|
||||
}
|
||||
@ -1697,21 +1697,31 @@ static void fill_included_packs_batch(struct repository *r,
|
||||
|
||||
total_size = 0;
|
||||
for (i = 0; total_size < batch_size && i < m->num_packs; i++) {
|
||||
int pack_int_id = pack_info[i].pack_int_id;
|
||||
uint32_t pack_int_id = pack_info[i].pack_int_id;
|
||||
struct packed_git *p = m->packs[pack_int_id];
|
||||
size_t expected_size;
|
||||
uint64_t expected_size;
|
||||
|
||||
if (!want_included_pack(r, m, pack_kept_objects, pack_int_id))
|
||||
continue;
|
||||
|
||||
expected_size = st_mult(p->pack_size,
|
||||
pack_info[i].referenced_objects);
|
||||
/*
|
||||
* Use shifted integer arithmetic to calculate the
|
||||
* expected pack size to ~4 significant digits without
|
||||
* overflow for packsizes less that 1PB.
|
||||
*/
|
||||
expected_size = (uint64_t)pack_info[i].referenced_objects << 14;
|
||||
expected_size /= p->num_objects;
|
||||
expected_size = u64_mult(expected_size, p->pack_size);
|
||||
expected_size = u64_add(expected_size, 1u << 13) >> 14;
|
||||
|
||||
if (expected_size >= batch_size)
|
||||
continue;
|
||||
|
||||
total_size += expected_size;
|
||||
if (unsigned_add_overflows(total_size, (size_t)expected_size))
|
||||
total_size = SIZE_MAX;
|
||||
else
|
||||
total_size += expected_size;
|
||||
|
||||
include_pack[pack_int_id] = 1;
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user