apply: avoid using fixed-size buffer in write_out_one_reject()
On some systems PATH_MAX is not a hard limit. Support longer paths by building them on the heap instead of using static buffers. Take care to work around (arguably buggy) implementations of free(3) that change errno by calling it only after using the errno value. Signed-off-by: René Scharfe <l.s.r@web.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
René Scharfe committed
Apr 16, 2024 at 22:16 UTC
20fee9af9e511a9086aa02992bd27035b914ee14
1 file changed
+17
-16
apply.c
+17
-16
@@ -4612,7 +4612,7 @@ static int write_out_one_result(struct apply_state *state,
4612
static int write_out_one_reject(struct apply_state *state, struct patch *patch)
4613
{
4614
FILE *rej;
4615
- char namebuf[PATH_MAX];
4615
+ char *namebuf;
4616
struct fragment *frag;
4617
int fd, cnt = 0;
4618
struct strbuf sb = STRBUF_INIT;
@@ -4645,30 +4645,29 @@ static int write_out_one_reject(struct apply_state *state, struct patch *patch)
4645
say_patch_name(stderr, sb.buf, patch);
4646
strbuf_release(&sb);
4647
4648
- cnt = strlen(patch->new_name);
4649
- if (ARRAY_SIZE(namebuf) <= cnt + 5) {
4650
- cnt = ARRAY_SIZE(namebuf) - 5;
4651
- warning(_("truncating .rej filename to %.*s.rej"),
4652
- cnt - 1, patch->new_name);
4653
- }
4654
- memcpy(namebuf, patch->new_name, cnt);
4655
- memcpy(namebuf + cnt, ".rej", 5);
4648
+ namebuf = xstrfmt("%s.rej", patch->new_name);
4649
4650
fd = open(namebuf, O_CREAT | O_EXCL | O_WRONLY, 0666);
4651
if (fd < 0) {
4659
- if (errno != EEXIST)
4660
- return error_errno(_("cannot open %s"), namebuf);
4661
- if (unlink(namebuf))
4662
- return error_errno(_("cannot unlink '%s'"), namebuf);
4652
+ if (errno != EEXIST) {
4653
+ error_errno(_("cannot open %s"), namebuf);
4654
+ goto error;
4655
+ }
4656
+ if (unlink(namebuf)) {
4657
+ error_errno(_("cannot unlink '%s'"), namebuf);
4658
+ goto error;
4659
+ }
4660
fd = open(namebuf, O_CREAT | O_EXCL | O_WRONLY, 0666);
4664
- if (fd < 0)
4665
- return error_errno(_("cannot open %s"), namebuf);
4661
+ if (fd < 0) {
4662
+ error_errno(_("cannot open %s"), namebuf);
4663
+ goto error;
4664
+ }
4665
}
4666
rej = fdopen(fd, "w");
4667
if (!rej) {
4668
error_errno(_("cannot open %s"), namebuf);
4669
close(fd);
4671
- return -1;
4670
+ goto error;
4671
}
4672
4673
/* Normal git tools never deal with .rej, so do not pretend
@@ -4693,6 +4692,8 @@ static int write_out_one_reject(struct apply_state *state, struct patch *patch)
4692
fputc('\n', rej);
4693
}
4694
fclose(rej);
4695
+error:
4696
+ free(namebuf);
4697
return -1;
4698
}
4699