Skip to content

Commit 49767c3

Browse files
committed
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
2 parents 7c2abf1 + 655b856 commit 49767c3

File tree

8 files changed

+84
-45
lines changed

8 files changed

+84
-45
lines changed

builtin/multi-pack-index.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,8 @@ static int cmd_multi_pack_index_verify(int argc, const char **argv)
167167
usage_with_options(builtin_multi_pack_index_verify_usage,
168168
options);
169169

170+
FREE_AND_NULL(options);
171+
170172
return verify_midx_file(the_repository, opts.object_dir, opts.flags);
171173
}
172174

@@ -191,6 +193,8 @@ static int cmd_multi_pack_index_expire(int argc, const char **argv)
191193
usage_with_options(builtin_multi_pack_index_expire_usage,
192194
options);
193195

196+
FREE_AND_NULL(options);
197+
194198
return expire_midx_packs(the_repository, opts.object_dir, opts.flags);
195199
}
196200

builtin/pack-objects.c

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4148,11 +4148,10 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)
41484148
read_packs_list_from_stdin();
41494149
if (rev_list_unpacked)
41504150
add_unreachable_loose_objects();
4151-
} else if (!use_internal_rev_list)
4151+
} else if (!use_internal_rev_list) {
41524152
read_object_list_from_stdin();
4153-
else {
4153+
} else {
41544154
get_object_list(rp.nr, rp.v);
4155-
strvec_clear(&rp);
41564155
}
41574156
cleanup_preferred_base();
41584157
if (include_tag && nr_result)
@@ -4162,7 +4161,7 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)
41624161
the_repository);
41634162

41644163
if (non_empty && !nr_result)
4165-
return 0;
4164+
goto cleanup;
41664165
if (nr_result) {
41674166
trace2_region_enter("pack-objects", "prepare-pack",
41684167
the_repository);
@@ -4183,5 +4182,9 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)
41834182
" pack-reused %"PRIu32),
41844183
written, written_delta, reused, reused_delta,
41854184
reuse_packfile_objects);
4185+
4186+
cleanup:
4187+
strvec_clear(&rp);
4188+
41864189
return 0;
41874190
}

builtin/repack.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -258,9 +258,11 @@ static void repack_promisor_objects(const struct pack_objects_args *args,
258258
for_each_packed_object(write_oid, &cmd,
259259
FOR_EACH_OBJECT_PROMISOR_ONLY);
260260

261-
if (cmd.in == -1)
261+
if (cmd.in == -1) {
262262
/* No packed objects; cmd was never started */
263+
child_process_clear(&cmd);
263264
return;
265+
}
264266

265267
close(cmd.in);
266268

midx.c

Lines changed: 38 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -57,15 +57,15 @@ const unsigned char *get_midx_checksum(struct multi_pack_index *m)
5757
return m->data + m->data_len - the_hash_algo->rawsz;
5858
}
5959

60-
char *get_midx_filename(const char *object_dir)
60+
void get_midx_filename(struct strbuf *out, const char *object_dir)
6161
{
62-
return xstrfmt("%s/pack/multi-pack-index", object_dir);
62+
strbuf_addf(out, "%s/pack/multi-pack-index", object_dir);
6363
}
6464

65-
char *get_midx_rev_filename(struct multi_pack_index *m)
65+
void get_midx_rev_filename(struct strbuf *out, struct multi_pack_index *m)
6666
{
67-
return xstrfmt("%s/pack/multi-pack-index-%s.rev",
68-
m->object_dir, hash_to_hex(get_midx_checksum(m)));
67+
get_midx_filename(out, m->object_dir);
68+
strbuf_addf(out, "-%s.rev", hash_to_hex(get_midx_checksum(m)));
6969
}
7070

7171
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
8989
size_t midx_size;
9090
void *midx_map = NULL;
9191
uint32_t hash_version;
92-
char *midx_name = get_midx_filename(object_dir);
92+
struct strbuf midx_name = STRBUF_INIT;
9393
uint32_t i;
9494
const char *cur_pack_name;
9595
struct chunkfile *cf = NULL;
9696

97-
fd = git_open(midx_name);
97+
get_midx_filename(&midx_name, object_dir);
98+
99+
fd = git_open(midx_name.buf);
98100

99101
if (fd < 0)
100102
goto cleanup_fail;
101103
if (fstat(fd, &st)) {
102-
error_errno(_("failed to read %s"), midx_name);
104+
error_errno(_("failed to read %s"), midx_name.buf);
103105
goto cleanup_fail;
104106
}
105107

106108
midx_size = xsize_t(st.st_size);
107109

108110
if (midx_size < MIDX_MIN_SIZE) {
109-
error(_("multi-pack-index file %s is too small"), midx_name);
111+
error(_("multi-pack-index file %s is too small"), midx_name.buf);
110112
goto cleanup_fail;
111113
}
112114

113-
FREE_AND_NULL(midx_name);
115+
strbuf_release(&midx_name);
114116

115117
midx_map = xmmap(NULL, midx_size, PROT_READ, MAP_PRIVATE, fd, 0);
116118
close(fd);
@@ -179,12 +181,13 @@ struct multi_pack_index *load_multi_pack_index(const char *object_dir, int local
179181
trace2_data_intmax("midx", the_repository, "load/num_packs", m->num_packs);
180182
trace2_data_intmax("midx", the_repository, "load/num_objects", m->num_objects);
181183

184+
free_chunkfile(cf);
182185
return m;
183186

184187
cleanup_fail:
185188
free(m);
186-
free(midx_name);
187-
free(cf);
189+
strbuf_release(&midx_name);
190+
free_chunkfile(cf);
188191
if (midx_map)
189192
munmap(midx_map, midx_size);
190193
if (0 <= fd)
@@ -1130,7 +1133,7 @@ static int write_midx_internal(const char *object_dir,
11301133
const char *refs_snapshot,
11311134
unsigned flags)
11321135
{
1133-
char *midx_name;
1136+
struct strbuf midx_name = STRBUF_INIT;
11341137
unsigned char midx_hash[GIT_MAX_RAWSZ];
11351138
uint32_t i;
11361139
struct hashfile *f = NULL;
@@ -1141,10 +1144,10 @@ static int write_midx_internal(const char *object_dir,
11411144
int result = 0;
11421145
struct chunkfile *cf;
11431146

1144-
midx_name = get_midx_filename(object_dir);
1145-
if (safe_create_leading_directories(midx_name))
1147+
get_midx_filename(&midx_name, object_dir);
1148+
if (safe_create_leading_directories(midx_name.buf))
11461149
die_errno(_("unable to create leading directories of %s"),
1147-
midx_name);
1150+
midx_name.buf);
11481151

11491152
if (!packs_to_include) {
11501153
/*
@@ -1373,7 +1376,7 @@ static int write_midx_internal(const char *object_dir,
13731376
pack_name_concat_len += MIDX_CHUNK_ALIGNMENT -
13741377
(pack_name_concat_len % MIDX_CHUNK_ALIGNMENT);
13751378

1376-
hold_lock_file_for_update(&lk, midx_name, LOCK_DIE_ON_ERROR);
1379+
hold_lock_file_for_update(&lk, midx_name.buf, LOCK_DIE_ON_ERROR);
13771380
f = hashfd(get_lock_file_fd(&lk), get_lock_file_path(&lk));
13781381

13791382
if (ctx.nr - dropped_packs == 0) {
@@ -1410,9 +1413,9 @@ static int write_midx_internal(const char *object_dir,
14101413
ctx.pack_order = midx_pack_order(&ctx);
14111414

14121415
if (flags & MIDX_WRITE_REV_INDEX)
1413-
write_midx_reverse_index(midx_name, midx_hash, &ctx);
1416+
write_midx_reverse_index(midx_name.buf, midx_hash, &ctx);
14141417
if (flags & MIDX_WRITE_BITMAP) {
1415-
if (write_midx_bitmap(midx_name, midx_hash, &ctx,
1418+
if (write_midx_bitmap(midx_name.buf, midx_hash, &ctx,
14161419
refs_snapshot, flags) < 0) {
14171420
error(_("could not write multi-pack bitmap"));
14181421
result = 1;
@@ -1442,7 +1445,7 @@ static int write_midx_internal(const char *object_dir,
14421445
free(ctx.entries);
14431446
free(ctx.pack_perm);
14441447
free(ctx.pack_order);
1445-
free(midx_name);
1448+
strbuf_release(&midx_name);
14461449

14471450
return result;
14481451
}
@@ -1506,20 +1509,22 @@ static void clear_midx_files_ext(const char *object_dir, const char *ext,
15061509

15071510
void clear_midx_file(struct repository *r)
15081511
{
1509-
char *midx = get_midx_filename(r->objects->odb->path);
1512+
struct strbuf midx = STRBUF_INIT;
1513+
1514+
get_midx_filename(&midx, r->objects->odb->path);
15101515

15111516
if (r->objects && r->objects->multi_pack_index) {
15121517
close_midx(r->objects->multi_pack_index);
15131518
r->objects->multi_pack_index = NULL;
15141519
}
15151520

1516-
if (remove_path(midx))
1517-
die(_("failed to clear multi-pack-index at %s"), midx);
1521+
if (remove_path(midx.buf))
1522+
die(_("failed to clear multi-pack-index at %s"), midx.buf);
15181523

15191524
clear_midx_files_ext(r->objects->odb->path, ".bitmap", NULL);
15201525
clear_midx_files_ext(r->objects->odb->path, ".rev", NULL);
15211526

1522-
free(midx);
1527+
strbuf_release(&midx);
15231528
}
15241529

15251530
static int verify_midx_error;
@@ -1572,12 +1577,15 @@ int verify_midx_file(struct repository *r, const char *object_dir, unsigned flag
15721577
if (!m) {
15731578
int result = 0;
15741579
struct stat sb;
1575-
char *filename = get_midx_filename(object_dir);
1576-
if (!stat(filename, &sb)) {
1580+
struct strbuf filename = STRBUF_INIT;
1581+
1582+
get_midx_filename(&filename, object_dir);
1583+
1584+
if (!stat(filename.buf, &sb)) {
15771585
error(_("multi-pack-index file exists, but failed to parse"));
15781586
result = 1;
15791587
}
1580-
free(filename);
1588+
strbuf_release(&filename);
15811589
return result;
15821590
}
15831591

@@ -1610,7 +1618,7 @@ int verify_midx_file(struct repository *r, const char *object_dir, unsigned flag
16101618
* Remaining tests assume that we have objects, so we can
16111619
* return here.
16121620
*/
1613-
return verify_midx_error;
1621+
goto cleanup;
16141622
}
16151623

16161624
if (flags & MIDX_PROGRESS)
@@ -1688,7 +1696,9 @@ int verify_midx_file(struct repository *r, const char *object_dir, unsigned flag
16881696
}
16891697
stop_progress(&progress);
16901698

1699+
cleanup:
16911700
free(pairs);
1701+
close_midx(m);
16921702

16931703
return verify_midx_error;
16941704
}

midx.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,8 @@ struct multi_pack_index {
4848
#define MIDX_WRITE_BITMAP_HASH_CACHE (1 << 3)
4949

5050
const unsigned char *get_midx_checksum(struct multi_pack_index *m);
51-
char *get_midx_filename(const char *object_dir);
52-
char *get_midx_rev_filename(struct multi_pack_index *m);
51+
void get_midx_filename(struct strbuf *out, const char *object_dir);
52+
void get_midx_rev_filename(struct strbuf *out, struct multi_pack_index *m);
5353

5454
struct multi_pack_index *load_multi_pack_index(const char *object_dir, int local);
5555
int prepare_midx_pack(struct repository *r, struct multi_pack_index *m, uint32_t pack_int_id);

pack-bitmap.c

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -292,9 +292,12 @@ static int load_bitmap_entries_v1(struct bitmap_index *index)
292292

293293
char *midx_bitmap_filename(struct multi_pack_index *midx)
294294
{
295-
return xstrfmt("%s-%s.bitmap",
296-
get_midx_filename(midx->object_dir),
297-
hash_to_hex(get_midx_checksum(midx)));
295+
struct strbuf buf = STRBUF_INIT;
296+
297+
get_midx_filename(&buf, midx->object_dir);
298+
strbuf_addf(&buf, "-%s.bitmap", hash_to_hex(get_midx_checksum(midx)));
299+
300+
return strbuf_detach(&buf, NULL);
298301
}
299302

300303
char *pack_bitmap_filename(struct packed_git *p)
@@ -324,10 +327,12 @@ static int open_midx_bitmap_1(struct bitmap_index *bitmap_git,
324327
}
325328

326329
if (bitmap_git->pack || bitmap_git->midx) {
330+
struct strbuf buf = STRBUF_INIT;
331+
get_midx_filename(&buf, midx->object_dir);
327332
/* ignore extra bitmap file; we can only handle one */
328-
warning("ignoring extra bitmap file: %s",
329-
get_midx_filename(midx->object_dir));
333+
warning("ignoring extra bitmap file: %s", buf.buf);
330334
close(fd);
335+
strbuf_release(&buf);
331336
return -1;
332337
}
333338

@@ -1721,6 +1726,12 @@ void test_bitmap_walk(struct rev_info *revs)
17211726
else
17221727
die("mismatch in bitmap results");
17231728

1729+
bitmap_free(result);
1730+
bitmap_free(tdata.base);
1731+
bitmap_free(tdata.commits);
1732+
bitmap_free(tdata.trees);
1733+
bitmap_free(tdata.blobs);
1734+
bitmap_free(tdata.tags);
17241735
free_bitmap_index(bitmap_git);
17251736
}
17261737

@@ -1848,9 +1859,17 @@ void free_bitmap_index(struct bitmap_index *b)
18481859
ewah_pool_free(b->trees);
18491860
ewah_pool_free(b->blobs);
18501861
ewah_pool_free(b->tags);
1862+
if (b->bitmaps) {
1863+
struct stored_bitmap *sb;
1864+
kh_foreach_value(b->bitmaps, sb, {
1865+
ewah_pool_free(sb->root);
1866+
free(sb);
1867+
});
1868+
}
18511869
kh_destroy_oid_map(b->bitmaps);
18521870
free(b->ext_index.objects);
18531871
free(b->ext_index.hashes);
1872+
kh_destroy_oid_pos(b->ext_index.positions);
18541873
bitmap_free(b->result);
18551874
bitmap_free(b->haves);
18561875
if (bitmap_is_midx(b)) {

pack-revindex.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -296,14 +296,14 @@ int load_pack_revindex(struct packed_git *p)
296296

297297
int load_midx_revindex(struct multi_pack_index *m)
298298
{
299-
char *revindex_name;
299+
struct strbuf revindex_name = STRBUF_INIT;
300300
int ret;
301301
if (m->revindex_data)
302302
return 0;
303303

304-
revindex_name = get_midx_rev_filename(m);
304+
get_midx_rev_filename(&revindex_name, m);
305305

306-
ret = load_revindex_from_disk(revindex_name,
306+
ret = load_revindex_from_disk(revindex_name.buf,
307307
m->num_objects,
308308
&m->revindex_map,
309309
&m->revindex_len);
@@ -313,7 +313,7 @@ int load_midx_revindex(struct multi_pack_index *m)
313313
m->revindex_data = (const uint32_t *)((const char *)m->revindex_map + RIDX_HEADER_SIZE);
314314

315315
cleanup:
316-
free(revindex_name);
316+
strbuf_release(&revindex_name);
317317
return ret;
318318
}
319319

t/helper/test-read-midx.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,9 +55,10 @@ static int read_midx_file(const char *object_dir, int show_objects)
5555
printf("%s %"PRIu64"\t%s\n",
5656
oid_to_hex(&oid), e.offset, e.p->pack_name);
5757
}
58-
return 0;
5958
}
6059

60+
close_midx(m);
61+
6162
return 0;
6263
}
6364

0 commit comments

Comments
 (0)