mirror of
https://github.com/git/git
synced 2024-10-04 07:39:24 +00: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:
parent
3c2a3fdc38
commit
9126cb3186
15
apply.c
15
apply.c
|
@ -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,
|
||||||
|
|
Loading…
Reference in a new issue