summaryrefslogtreecommitdiff
path: root/midx.c
diff options
context:
space:
mode:
authorJunio C Hamano <gitster@pobox.com>2021-11-29 23:41:49 (GMT)
committerJunio C Hamano <gitster@pobox.com>2021-11-29 23:41:49 (GMT)
commit49767c3d9f80c916c175adfc745e0823487d9d08 (patch)
treeeeff328ee4dc916e14a336abfb2cd8c79a6b346b /midx.c
parent7c2abf1a83efa13ffc03a3847f774cf85ffce913 (diff)
parent655b8561d6b10f22f0e7350df9388110667001af (diff)
downloadgit-49767c3d9f80c916c175adfc745e0823487d9d08.zip
git-49767c3d9f80c916c175adfc745e0823487d9d08.tar.gz
git-49767c3d9f80c916c175adfc745e0823487d9d08.tar.bz2
Merge branch 'tb/plug-pack-bitmap-leaks'
Leakfix. * tb/plug-pack-bitmap-leaks: pack-bitmap.c: more aggressively free in free_bitmap_index() pack-bitmap.c: don't leak type-level bitmaps midx.c: write MIDX filenames to strbuf builtin/multi-pack-index.c: don't leak concatenated options builtin/repack.c: avoid leaking child arguments builtin/pack-objects.c: don't leak memory via arguments t/helper/test-read-midx.c: free MIDX within read_midx_file() midx.c: don't leak MIDX from verify_midx_file midx.c: clean up chunkfile after reading the MIDX
Diffstat (limited to 'midx.c')
-rw-r--r--midx.c66
1 files changed, 38 insertions, 28 deletions
diff --git a/midx.c b/midx.c
index 8433086..837b46b 100644
--- a/midx.c
+++ b/midx.c
@@ -57,15 +57,15 @@ const unsigned char *get_midx_checksum(struct multi_pack_index *m)
return m->data + m->data_len - the_hash_algo->rawsz;
}
-char *get_midx_filename(const char *object_dir)
+void get_midx_filename(struct strbuf *out, const char *object_dir)
{
- return xstrfmt("%s/pack/multi-pack-index", object_dir);
+ strbuf_addf(out, "%s/pack/multi-pack-index", object_dir);
}
-char *get_midx_rev_filename(struct multi_pack_index *m)
+void get_midx_rev_filename(struct strbuf *out, struct multi_pack_index *m)
{
- return xstrfmt("%s/pack/multi-pack-index-%s.rev",
- m->object_dir, hash_to_hex(get_midx_checksum(m)));
+ get_midx_filename(out, m->object_dir);
+ strbuf_addf(out, "-%s.rev", hash_to_hex(get_midx_checksum(m)));
}
static int midx_read_oid_fanout(const unsigned char *chunk_start,
@@ -89,28 +89,30 @@ struct multi_pack_index *load_multi_pack_index(const char *object_dir, int local
size_t midx_size;
void *midx_map = NULL;
uint32_t hash_version;
- char *midx_name = get_midx_filename(object_dir);
+ struct strbuf midx_name = STRBUF_INIT;
uint32_t i;
const char *cur_pack_name;
struct chunkfile *cf = NULL;
- fd = git_open(midx_name);
+ get_midx_filename(&midx_name, object_dir);
+
+ fd = git_open(midx_name.buf);
if (fd < 0)
goto cleanup_fail;
if (fstat(fd, &st)) {
- error_errno(_("failed to read %s"), midx_name);
+ error_errno(_("failed to read %s"), midx_name.buf);
goto cleanup_fail;
}
midx_size = xsize_t(st.st_size);
if (midx_size < MIDX_MIN_SIZE) {
- error(_("multi-pack-index file %s is too small"), midx_name);
+ error(_("multi-pack-index file %s is too small"), midx_name.buf);
goto cleanup_fail;
}
- FREE_AND_NULL(midx_name);
+ strbuf_release(&midx_name);
midx_map = xmmap(NULL, midx_size, PROT_READ, MAP_PRIVATE, fd, 0);
close(fd);
@@ -179,12 +181,13 @@ struct multi_pack_index *load_multi_pack_index(const char *object_dir, int local
trace2_data_intmax("midx", the_repository, "load/num_packs", m->num_packs);
trace2_data_intmax("midx", the_repository, "load/num_objects", m->num_objects);
+ free_chunkfile(cf);
return m;
cleanup_fail:
free(m);
- free(midx_name);
- free(cf);
+ strbuf_release(&midx_name);
+ free_chunkfile(cf);
if (midx_map)
munmap(midx_map, midx_size);
if (0 <= fd)
@@ -1130,7 +1133,7 @@ static int write_midx_internal(const char *object_dir,
const char *refs_snapshot,
unsigned flags)
{
- char *midx_name;
+ struct strbuf midx_name = STRBUF_INIT;
unsigned char midx_hash[GIT_MAX_RAWSZ];
uint32_t i;
struct hashfile *f = NULL;
@@ -1141,10 +1144,10 @@ static int write_midx_internal(const char *object_dir,
int result = 0;
struct chunkfile *cf;
- midx_name = get_midx_filename(object_dir);
- if (safe_create_leading_directories(midx_name))
+ get_midx_filename(&midx_name, object_dir);
+ if (safe_create_leading_directories(midx_name.buf))
die_errno(_("unable to create leading directories of %s"),
- midx_name);
+ midx_name.buf);
if (!packs_to_include) {
/*
@@ -1373,7 +1376,7 @@ static int write_midx_internal(const char *object_dir,
pack_name_concat_len += MIDX_CHUNK_ALIGNMENT -
(pack_name_concat_len % MIDX_CHUNK_ALIGNMENT);
- hold_lock_file_for_update(&lk, midx_name, LOCK_DIE_ON_ERROR);
+ hold_lock_file_for_update(&lk, midx_name.buf, LOCK_DIE_ON_ERROR);
f = hashfd(get_lock_file_fd(&lk), get_lock_file_path(&lk));
if (ctx.nr - dropped_packs == 0) {
@@ -1410,9 +1413,9 @@ static int write_midx_internal(const char *object_dir,
ctx.pack_order = midx_pack_order(&ctx);
if (flags & MIDX_WRITE_REV_INDEX)
- write_midx_reverse_index(midx_name, midx_hash, &ctx);
+ write_midx_reverse_index(midx_name.buf, midx_hash, &ctx);
if (flags & MIDX_WRITE_BITMAP) {
- if (write_midx_bitmap(midx_name, midx_hash, &ctx,
+ if (write_midx_bitmap(midx_name.buf, midx_hash, &ctx,
refs_snapshot, flags) < 0) {
error(_("could not write multi-pack bitmap"));
result = 1;
@@ -1442,7 +1445,7 @@ cleanup:
free(ctx.entries);
free(ctx.pack_perm);
free(ctx.pack_order);
- free(midx_name);
+ strbuf_release(&midx_name);
return result;
}
@@ -1506,20 +1509,22 @@ static void clear_midx_files_ext(const char *object_dir, const char *ext,
void clear_midx_file(struct repository *r)
{
- char *midx = get_midx_filename(r->objects->odb->path);
+ struct strbuf midx = STRBUF_INIT;
+
+ get_midx_filename(&midx, r->objects->odb->path);
if (r->objects && r->objects->multi_pack_index) {
close_midx(r->objects->multi_pack_index);
r->objects->multi_pack_index = NULL;
}
- if (remove_path(midx))
- die(_("failed to clear multi-pack-index at %s"), midx);
+ if (remove_path(midx.buf))
+ die(_("failed to clear multi-pack-index at %s"), midx.buf);
clear_midx_files_ext(r->objects->odb->path, ".bitmap", NULL);
clear_midx_files_ext(r->objects->odb->path, ".rev", NULL);
- free(midx);
+ strbuf_release(&midx);
}
static int verify_midx_error;
@@ -1572,12 +1577,15 @@ int verify_midx_file(struct repository *r, const char *object_dir, unsigned flag
if (!m) {
int result = 0;
struct stat sb;
- char *filename = get_midx_filename(object_dir);
- if (!stat(filename, &sb)) {
+ struct strbuf filename = STRBUF_INIT;
+
+ get_midx_filename(&filename, object_dir);
+
+ if (!stat(filename.buf, &sb)) {
error(_("multi-pack-index file exists, but failed to parse"));
result = 1;
}
- free(filename);
+ strbuf_release(&filename);
return result;
}
@@ -1610,7 +1618,7 @@ int verify_midx_file(struct repository *r, const char *object_dir, unsigned flag
* Remaining tests assume that we have objects, so we can
* return here.
*/
- return verify_midx_error;
+ goto cleanup;
}
if (flags & MIDX_PROGRESS)
@@ -1688,7 +1696,9 @@ int verify_midx_file(struct repository *r, const char *object_dir, unsigned flag
}
stop_progress(&progress);
+cleanup:
free(pairs);
+ close_midx(m);
return verify_midx_error;
}