Skip to content

Commit f207548

Browse files
peffgitster
authored andcommitted
index-pack: make pointer-alias fallbacks safer
The final() function accepts a NULL value for certain parameters, and falls back to writing into a reusable "name" buffer, and then either: 1. For "keep_name", requiring all uses to do "keep_name ? keep_name : name.buf". This is awkward, and it's easy to accidentally look at the maybe-NULL keep_name. 2. For "final_index_name" and "final_pack_name", aliasing those pointers to the "name" buffer. This is easier to use, but the aliased pointers become invalid after the buffer is reused (this isn't a bug now, but it's a potential pitfall). One way to make this safer would be to introduce an extra pointer to do the aliasing, and have its lifetime match the validity of the "name" buffer. But it's still easy to accidentally use the wrong name (i.e., to use "final_pack_name" instead of the aliased pointer). Instead, let's use three separate buffers that will remain valid through the function. That makes it safe to alias the pointers and use them consistently. The extra allocations shouldn't matter, as this function is not performance sensitive. Signed-off-by: Jeff King <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent ba47a30 commit f207548

File tree

1 file changed

+12
-8
lines changed

1 file changed

+12
-8
lines changed

builtin/index-pack.c

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1386,7 +1386,9 @@ static void final(const char *final_pack_name, const char *curr_pack_name,
13861386
unsigned char *sha1)
13871387
{
13881388
const char *report = "pack";
1389-
struct strbuf name = STRBUF_INIT;
1389+
struct strbuf pack_name = STRBUF_INIT;
1390+
struct strbuf index_name = STRBUF_INIT;
1391+
struct strbuf keep_name_buf = STRBUF_INIT;
13901392
int err;
13911393

13921394
if (!from_stdin) {
@@ -1402,36 +1404,36 @@ static void final(const char *final_pack_name, const char *curr_pack_name,
14021404
int keep_fd, keep_msg_len = strlen(keep_msg);
14031405

14041406
if (!keep_name)
1405-
odb_pack_name(&name, sha1, "keep");
1407+
keep_name = odb_pack_name(&keep_name_buf, sha1, "keep");
14061408

1407-
keep_fd = odb_pack_keep(keep_name ? keep_name : name.buf);
1409+
keep_fd = odb_pack_keep(keep_name);
14081410
if (keep_fd < 0) {
14091411
if (errno != EEXIST)
14101412
die_errno(_("cannot write keep file '%s'"),
1411-
keep_name ? keep_name : name.buf);
1413+
keep_name);
14121414
} else {
14131415
if (keep_msg_len > 0) {
14141416
write_or_die(keep_fd, keep_msg, keep_msg_len);
14151417
write_or_die(keep_fd, "\n", 1);
14161418
}
14171419
if (close(keep_fd) != 0)
14181420
die_errno(_("cannot close written keep file '%s'"),
1419-
keep_name ? keep_name : name.buf);
1421+
keep_name);
14201422
report = "keep";
14211423
}
14221424
}
14231425

14241426
if (final_pack_name != curr_pack_name) {
14251427
if (!final_pack_name)
1426-
final_pack_name = odb_pack_name(&name, sha1, "pack");
1428+
final_pack_name = odb_pack_name(&pack_name, sha1, "pack");
14271429
if (finalize_object_file(curr_pack_name, final_pack_name))
14281430
die(_("cannot store pack file"));
14291431
} else if (from_stdin)
14301432
chmod(final_pack_name, 0444);
14311433

14321434
if (final_index_name != curr_index_name) {
14331435
if (!final_index_name)
1434-
final_index_name = odb_pack_name(&name, sha1, "idx");
1436+
final_index_name = odb_pack_name(&index_name, sha1, "idx");
14351437
if (finalize_object_file(curr_index_name, final_index_name))
14361438
die(_("cannot store index file"));
14371439
} else
@@ -1458,7 +1460,9 @@ static void final(const char *final_pack_name, const char *curr_pack_name,
14581460
}
14591461
}
14601462

1461-
strbuf_release(&name);
1463+
strbuf_release(&index_name);
1464+
strbuf_release(&pack_name);
1465+
strbuf_release(&keep_name_buf);
14621466
}
14631467

14641468
static int git_index_pack_config(const char *k, const char *v, void *cb)

0 commit comments

Comments
 (0)