From 9126cb3186112f160a601e9a7eda29dd43227576 Mon Sep 17 00:00:00 2001 From: René Scharfe Date: Fri, 5 Apr 2024 12:53:23 +0200 Subject: apply: avoid fixed-size buffer in create_one_file() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 Helped-by: Jeff King Signed-off-by: René Scharfe Signed-off-by: Junio C Hamano --- apply.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/apply.c b/apply.c index 7608e3301c..925dbde713 100644 --- a/apply.c +++ b/apply.c @@ -4430,6 +4430,7 @@ static int create_one_file(struct apply_state *state, const char *buf, unsigned long size) { + char *newpath = NULL; int res; if (state->cached) @@ -4491,24 +4492,26 @@ static int create_one_file(struct apply_state *state, unsigned int nr = getpid(); for (;;) { - char newpath[PATH_MAX]; - mksnpath(newpath, sizeof(newpath), "%s~%u", path, nr); + newpath = mkpathdup("%s~%u", path, nr); res = try_create_file(state, newpath, mode, buf, size); if (res < 0) - return -1; + goto out; if (!res) { if (!rename(newpath, path)) - return 0; + goto out; unlink_or_warn(newpath); break; } if (errno != EEXIST) break; ++nr; + FREE_AND_NULL(newpath); } } - return error_errno(_("unable to write file '%s' mode %o"), - path, mode); + res = error_errno(_("unable to write file '%s' mode %o"), path, mode); +out: + free(newpath); + return res; } static int add_conflicted_stages_file(struct apply_state *state, -- cgit 1.2.3-korg From 708f7e05907ba7d4acd08bf87f51474471a16f43 Mon Sep 17 00:00:00 2001 From: René Scharfe Date: Fri, 5 Apr 2024 12:56:48 +0200 Subject: path: remove mksnpath() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove the function mksnpath(), which has become unused. Signed-off-by: René Scharfe Signed-off-by: Junio C Hamano --- contrib/vscode/init.sh | 1 - path.c | 17 ----------------- path.h | 6 ------ 3 files changed, 24 deletions(-) diff --git a/contrib/vscode/init.sh b/contrib/vscode/init.sh index 521d303722..f2d61bb0e6 100755 --- a/contrib/vscode/init.sh +++ b/contrib/vscode/init.sh @@ -92,7 +92,6 @@ cat >.vscode/settings.json.new <<\EOF || "isexe", "iskeychar", "kompare", - "mksnpath", "mktag", "mktree", "mmblob", diff --git a/path.c b/path.c index 0fb527918b..9a62b6faae 100644 --- a/path.c +++ b/path.c @@ -28,8 +28,6 @@ static int get_st_mode_bits(const char *path, int *mode) return 0; } -static char bad_path[] = "/bad-path/"; - static struct strbuf *get_pathname(void) { static struct strbuf pathname_array[4] = { @@ -59,21 +57,6 @@ static void strbuf_cleanup_path(struct strbuf *sb) strbuf_remove(sb, 0, path - sb->buf); } -char *mksnpath(char *buf, size_t n, const char *fmt, ...) -{ - va_list args; - unsigned len; - - va_start(args, fmt); - len = vsnprintf(buf, n, fmt, args); - va_end(args); - if (len >= n) { - strlcpy(buf, bad_path, n); - return buf; - } - return (char *)cleanup_path(buf); -} - static int dir_prefix(const char *buf, const char *dir) { int len = strlen(dir); diff --git a/path.h b/path.h index b3233c51fa..54d39c770f 100644 --- a/path.h +++ b/path.h @@ -23,12 +23,6 @@ const char *mkpath(const char *fmt, ...) char *mkpathdup(const char *fmt, ...) __attribute__((format (printf, 1, 2))); -/* - * Construct a path and place the result in the provided buffer `buf`. - */ -char *mksnpath(char *buf, size_t n, const char *fmt, ...) - __attribute__((format (printf, 3, 4))); - /* * The `git_common_path` family of functions will construct a path into a * repository's common git directory, which is shared by all worktrees. -- cgit 1.2.3-korg