1
0
Fork 0
mirror of https://github.com/git/git.git synced 2024-05-24 00:16:31 +02:00

apply: avoid fixed-size buffer in create_one_file()

PATH_MAX is not always a hard limit and 'path' in create_one_file()
could be longer -- it's taken from the patch file and allocated
dynamically.  Allocate the name of the temporary file on the heap as
well instead of using a fixed-size buffer to avoid that arbitrary limit.

Resist the temptation of using the more convenient mkpath() to avoid
introducing a dependency on a static variable deep inside the apply
machinery.

Take care to work around (arguably buggy) implementations of free(3)
that modify errno, by calling it only after using the errno value.

Suggested-by: Jeff King <peff@peff.net>
Helped-by: Jeff King <peff@peff.net>
Signed-off-by: René Scharfe <l.s.r@web.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
René Scharfe 2024-04-05 12:53:23 +02:00 committed by Junio C Hamano
parent 3c2a3fdc38
commit 9126cb3186

15
apply.c
View File

@ -4430,6 +4430,7 @@ static int create_one_file(struct apply_state *state,
const char *buf, const char *buf,
unsigned long size) unsigned long size)
{ {
char *newpath = NULL;
int res; int res;
if (state->cached) if (state->cached)
@ -4491,24 +4492,26 @@ static int create_one_file(struct apply_state *state,
unsigned int nr = getpid(); unsigned int nr = getpid();
for (;;) { for (;;) {
char newpath[PATH_MAX]; newpath = mkpathdup("%s~%u", path, nr);
mksnpath(newpath, sizeof(newpath), "%s~%u", path, nr);
res = try_create_file(state, newpath, mode, buf, size); res = try_create_file(state, newpath, mode, buf, size);
if (res < 0) if (res < 0)
return -1; goto out;
if (!res) { if (!res) {
if (!rename(newpath, path)) if (!rename(newpath, path))
return 0; goto out;
unlink_or_warn(newpath); unlink_or_warn(newpath);
break; break;
} }
if (errno != EEXIST) if (errno != EEXIST)
break; break;
++nr; ++nr;
FREE_AND_NULL(newpath);
} }
} }
return error_errno(_("unable to write file '%s' mode %o"), res = error_errno(_("unable to write file '%s' mode %o"), path, mode);
path, mode); out:
free(newpath);
return res;
} }
static int add_conflicted_stages_file(struct apply_state *state, static int add_conflicted_stages_file(struct apply_state *state,