git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH] apply: avoid using fixed-size buffer in write_out_one_reject()

From
René Scharfe <l.s.r@web.de>
Date
Apr 16, 2024, 20:16 UTC
Message-ID
<a93cd243-cb17-4ad5-8d23-30768dc5213b@web.de>

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>
---
 apply.c | 33 +++++++++++++++++----------------
 1 file changed, 17 insertions(+), 16 deletions(-)
diff --git a/apply.c b/apply.c
index 34f20326a7..757009a39e 100644
--- a/apply.c
+++ b/apply.c
@@ -4612,7 +4612,7 @@ static int write_out_one_result(struct apply_state *state,
 static int write_out_one_reject(struct apply_state *state, struct patch *patch)
 {
 	FILE *rej;
-	char namebuf[PATH_MAX];
+	char *namebuf;
 	struct fragment *frag;
 	int fd, cnt = 0;
 	struct strbuf sb = STRBUF_INIT;
@@ -4645,30 +4645,29 @@ static int write_out_one_reject(struct apply_state *state, struct patch *patch)
 		say_patch_name(stderr, sb.buf, patch);
 	strbuf_release(&sb);

-	cnt = strlen(patch->new_name);
-	if (ARRAY_SIZE(namebuf) <= cnt + 5) {
-		cnt = ARRAY_SIZE(namebuf) - 5;
-		warning(_("truncating .rej filename to %.*s.rej"),
-			cnt - 1, patch->new_name);
-	}
-	memcpy(namebuf, patch->new_name, cnt);
-	memcpy(namebuf + cnt, ".rej", 5);
+	namebuf = xstrfmt("%s.rej", patch->new_name);

 	fd = open(namebuf, O_CREAT | O_EXCL | O_WRONLY, 0666);
 	if (fd < 0) {
-		if (errno != EEXIST)
-			return error_errno(_("cannot open %s"), namebuf);
-		if (unlink(namebuf))
-			return error_errno(_("cannot unlink '%s'"), namebuf);
+		if (errno != EEXIST) {
+			error_errno(_("cannot open %s"), namebuf);
+			goto error;
+		}
+		if (unlink(namebuf)) {
+			error_errno(_("cannot unlink '%s'"), namebuf);
+			goto error;
+		}
 		fd = open(namebuf, O_CREAT | O_EXCL | O_WRONLY, 0666);
-		if (fd < 0)
-			return error_errno(_("cannot open %s"), namebuf);
+		if (fd < 0) {
+			error_errno(_("cannot open %s"), namebuf);
+			goto error;
+		}
 	}
 	rej = fdopen(fd, "w");
 	if (!rej) {
 		error_errno(_("cannot open %s"), namebuf);
 		close(fd);
-		return -1;
+		goto error;
 	}

 	/* 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)
 			fputc('\n', rej);
 	}
 	fclose(rej);
+error:
+	free(namebuf);
 	return -1;
 }

--
2.44.0
Next: Junio C Hamano
Message 1 of 2 in “apply: avoid using fixed-size buffer in write_out_one_reject()”
  1. apply: avoid using fixed-size buffer in write_out_one_reject()René Scharfe, Apr 16, 2024
  2. Junio C HamanoApr 16, 2024

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.