stash: do not pass strbuf by value

save_untracked_files() takes its 'files' parameter as struct strbuf by value. Passing a strbuf by value copies the struct but shares the underlying buffer between caller and callee, risking a dangling pointer and double-free if the callee reallocates. The function needs both the buffer and its length for pipe_command(), so a plain const char * is not sufficient here. Switch the parameter to struct strbuf * and update the caller to pass a pointer. Signed-off-by: Deveshi Dwivedi <deveshigurgaon@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Deveshi Dwivedi committed Mar 15, 2026 at 09:44 UTC 8f8e1b080701d4b02ca3732eed2706b1a5328c5d
1 file changed +3 -3
builtin/stash.c
+3 -3
@@ -1232,7 +1232,7 @@ static int check_changes(const struct pathspec *ps, int include_untracked,
1232 }
1233
1234 static int save_untracked_files(struct stash_info *info, struct strbuf *msg,
1235 - struct strbuf files)
1235 + struct strbuf *files)
1236 {
1237 int ret = 0;
1238 struct strbuf untracked_msg = STRBUF_INIT;
@@ -1246,7 +1246,7 @@ static int save_untracked_files(struct stash_info *info, struct strbuf *msg,
1246 stash_index_path.buf);
1247
1248 strbuf_addf(&untracked_msg, "untracked files on %s\n", msg->buf);
1249 - if (pipe_command(&cp_upd_index, files.buf, files.len, NULL, 0,
1249 + if (pipe_command(&cp_upd_index, files->buf, files->len, NULL, 0,
1250 NULL, 0)) {
1251 ret = -1;
1252 goto done;
@@ -1499,7 +1499,7 @@ static int do_create_stash(const struct pathspec *ps, struct strbuf *stash_msg_b
1499 parents = NULL;
1500
1501 if (include_untracked) {
1502 - if (save_untracked_files(info, &msg, untracked_files)) {
1502 + if (save_untracked_files(info, &msg, &untracked_files)) {
1503 if (!quiet)
1504 fprintf_ln(stderr, _("Cannot save "
1505 "the untracked files"));