Skip to content

Commit 20fee9a

Browse files
rscharfegitster
authored andcommitted
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 <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 548fe35 commit 20fee9a

File tree

1 file changed

+17
-16
lines changed

1 file changed

+17
-16
lines changed

apply.c

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4612,7 +4612,7 @@ static int write_out_one_result(struct apply_state *state,
46124612
static int write_out_one_reject(struct apply_state *state, struct patch *patch)
46134613
{
46144614
FILE *rej;
4615-
char namebuf[PATH_MAX];
4615+
char *namebuf;
46164616
struct fragment *frag;
46174617
int fd, cnt = 0;
46184618
struct strbuf sb = STRBUF_INIT;
@@ -4645,30 +4645,29 @@ static int write_out_one_reject(struct apply_state *state, struct patch *patch)
46454645
say_patch_name(stderr, sb.buf, patch);
46464646
strbuf_release(&sb);
46474647

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);
46564649

46574650
fd = open(namebuf, O_CREAT | O_EXCL | O_WRONLY, 0666);
46584651
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+
}
46634660
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+
}
46664665
}
46674666
rej = fdopen(fd, "w");
46684667
if (!rej) {
46694668
error_errno(_("cannot open %s"), namebuf);
46704669
close(fd);
4671-
return -1;
4670+
goto error;
46724671
}
46734672

46744673
/* 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)
46934692
fputc('\n', rej);
46944693
}
46954694
fclose(rej);
4695+
error:
4696+
free(namebuf);
46964697
return -1;
46974698
}
46984699

0 commit comments

Comments
 (0)