diff --git a/src/buffer.c b/src/buffer.c index 43cba3ad8c..a903ab3753 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -3948,9 +3948,8 @@ fileinfo( name = curbuf->b_fname; else name = curbuf->b_ffname; - home_replace(shorthelp ? curbuf : NULL, name, (char_u *)buffer + bufferlen, - IOSIZE - (int)bufferlen, TRUE); - bufferlen += STRLEN(buffer + bufferlen); + bufferlen += home_replace(shorthelp ? curbuf : NULL, name, + (char_u *)buffer + bufferlen, IOSIZE - (int)bufferlen, TRUE); } bufferlen += vim_snprintf_safelen( diff --git a/src/fileio.c b/src/fileio.c index 1a7ee9b94d..af0360dc8c 100644 --- a/src/fileio.c +++ b/src/fileio.c @@ -3200,11 +3200,13 @@ set_rw_fname(char_u *fname, char_u *sfname) void msg_add_fname(buf_T *buf, char_u *fname) { + size_t IObufflen = 0; + if (fname == NULL) fname = (char_u *)"-stdin-"; - home_replace(buf, fname, IObuff + 1, IOSIZE - 4, TRUE); - IObuff[0] = '"'; - STRCAT(IObuff, "\" "); + IObuff[IObufflen++] = '"'; + IObufflen += home_replace(buf, fname, IObuff + IObufflen, IOSIZE - 4, TRUE); + STRCPY(IObuff + IObufflen, "\" "); } /* diff --git a/src/filepath.c b/src/filepath.c index a41f8c27fc..8bdba335c6 100644 --- a/src/filepath.c +++ b/src/filepath.c @@ -442,27 +442,29 @@ repeat: if (p != NULL) { + size_t dirnamelen = 0; + if (c == '.') { - size_t namelen; - mch_dirname(dirname, MAXPATHL); if (has_homerelative) { s = vim_strsave(dirname); if (s != NULL) { - home_replace(NULL, s, dirname, MAXPATHL, TRUE); + dirnamelen = home_replace(NULL, s, dirname, MAXPATHL, TRUE); vim_free(s); } } - namelen = STRLEN(dirname); + + if (dirnamelen == 0) + dirnamelen = STRLEN(dirname); // Do not call shorten_fname() here since it removes the prefix // even though the path does not have a prefix. - if (fnamencmp(p, dirname, namelen) == 0) + if (fnamencmp(p, dirname, dirnamelen) == 0) { - p += namelen; + p += dirnamelen; if (vim_ispathsep(*p)) { while (*p && vim_ispathsep(*p)) @@ -480,11 +482,11 @@ repeat: } else { - home_replace(NULL, p, dirname, MAXPATHL, TRUE); + dirnamelen = home_replace(NULL, p, dirname, MAXPATHL, TRUE); // Only replace it when it starts with '~' if (*dirname == '~') { - s = vim_strsave(dirname); + s = vim_strnsave(dirname, dirnamelen); if (s != NULL) { *fnamep = s; @@ -2724,7 +2726,7 @@ f_filecopy(typval_T *argvars, typval_T *rettv) * 'src'. * If anything fails (except when out of space) dst equals src. */ - void + size_t home_replace( buf_T *buf, // when not NULL, check for help files char_u *src, // input file name @@ -2737,21 +2739,19 @@ home_replace( size_t len; char_u *homedir_env, *homedir_env_orig; char_u *p; + char_u *dst_start; if (src == NULL) { *dst = NUL; - return; + return 0; } /* * If the file is a help file, remove the path completely. */ if (buf != NULL && buf->b_help) - { - vim_snprintf((char *)dst, dstlen, "%s", gettail(src)); - return; - } + return vim_snprintf_safelen((char *)dst, dstlen, "%s", gettail(src)); /* * We check both the value of the $HOME environment variable and the @@ -2793,6 +2793,7 @@ home_replace( if (!one) src = skipwhite(src); + dst_start = dst; // remember the start while (*src && dstlen > 0) { /* @@ -2842,6 +2843,8 @@ home_replace( if (homedir_env != homedir_env_orig) vim_free(homedir_env); + + return (size_t)(dst - dst_start); } /* diff --git a/src/memline.c b/src/memline.c index ffd3fbd72a..51b09cc1ca 100644 --- a/src/memline.c +++ b/src/memline.c @@ -1021,7 +1021,7 @@ set_b0_fname(ZERO_BL *b0p, buf_T *buf) forward_slash(b0p->b0_fname); # endif #else - size_t flen, ulen; + size_t flen; char_u uname[B0_UNAME_SIZE]; /* @@ -1031,11 +1031,12 @@ set_b0_fname(ZERO_BL *b0p, buf_T *buf) * First replace home dir path with "~/" with home_replace(). * Then insert the user name to get "~user/". */ - home_replace(NULL, buf->b_ffname, b0p->b0_fname, + flen = home_replace(NULL, buf->b_ffname, b0p->b0_fname, B0_FNAME_SIZE_CRYPT, TRUE); if (b0p->b0_fname[0] == '~') { - flen = STRLEN(b0p->b0_fname); + size_t ulen; + // If there is no user name or it is too long, don't use "~/" if (get_user_name(uname, B0_UNAME_SIZE) == FAIL || (ulen = STRLEN(uname)) + flen > B0_FNAME_SIZE_CRYPT - 1) @@ -5343,24 +5344,32 @@ findswapname( if (swap_exists_action != SEA_NONE && choice == SEA_CHOICE_NONE) { - char_u *name; - int dialog_result; - size_t len = STRLEN(_("Swap file \"")); + string_T prefix = {(char_u *)_("Swap file \""), 0}; + string_T suffix = {(char_u *)_("\" already exists!"), 0}; + size_t message_size; + string_T message; + char_u *tofree; + int dialog_result; - name = alloc(STRLEN(fname) - + len - + STRLEN(_("\" already exists!")) + 5); - if (name != NULL) + prefix.length = STRLEN(prefix.string); + suffix.length = STRLEN(suffix.string); + message_size = prefix.length + + STRLEN(fname) + + suffix.length + 5; + message.string = tofree = alloc(message_size); + if (message.string != NULL) { - STRCPY(name, _("Swap file \"")); - home_replace(NULL, fname, name + len, 1000, TRUE); - STRCAT(name, _("\" already exists!")); + STRCPY(message.string, prefix.string); + message.length = prefix.length; + message.length += home_replace(NULL, fname, + message.string + message.length, (int)(message_size - message.length), TRUE); + STRCPY(message.string + message.length, suffix.string); } + else + message.string = (char_u *)_("Swap file already exists!"); dialog_result = do_dialog(VIM_WARNING, (char_u *)_("VIM - ATTENTION"), - name == NULL - ? (char_u *)_("Swap file already exists!") - : name, + message.string, # ifdef HAVE_PROCESS_STILL_RUNNING process_still_running ? (char_u *)_("&Open Read-Only\n&Edit anyway\n&Recover\n&Quit\n&Abort") : @@ -5373,7 +5382,7 @@ findswapname( dialog_result++; # endif choice = dialog_result; - vim_free(name); + vim_free(tofree); // pretend screen didn't scroll, need redraw anyway msg_scrolled = 0; diff --git a/src/po/vim.pot b/src/po/vim.pot index 2057c23a92..e5cf8c102d 100644 --- a/src/po/vim.pot +++ b/src/po/vim.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: Vim\n" "Report-Msgid-Bugs-To: vim-dev@vim.org\n" -"POT-Creation-Date: 2026-05-19 18:20+0000\n" +"POT-Creation-Date: 2026-05-20 18:41+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -2169,10 +2169,10 @@ msgstr "" msgid "\" already exists!" msgstr "" -msgid "VIM - ATTENTION" +msgid "Swap file already exists!" msgstr "" -msgid "Swap file already exists!" +msgid "VIM - ATTENTION" msgstr "" msgid "" diff --git a/src/proto/filepath.pro b/src/proto/filepath.pro index d00a66775f..ac87623834 100644 --- a/src/proto/filepath.pro +++ b/src/proto/filepath.pro @@ -36,7 +36,7 @@ char_u *do_browse(int flags, char_u *title, char_u *dflt, char_u *ext, char_u *i void f_browse(typval_T *argvars, typval_T *rettv); void f_browsedir(typval_T *argvars, typval_T *rettv); void f_filecopy(typval_T *argvars, typval_T *rettv); -void home_replace(buf_T *buf, char_u *src, char_u *dst, int dstlen, int one); +size_t home_replace(buf_T *buf, char_u *src, char_u *dst, int dstlen, int one); char_u *home_replace_save(buf_T *buf, char_u *src); int fullpathcmp(char_u *s1, char_u *s2, int checkname, int expandenv); char_u *gettail(char_u *fname); diff --git a/src/version.c b/src/version.c index f46d48acc3..dc31e54a77 100644 --- a/src/version.c +++ b/src/version.c @@ -729,6 +729,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 506, /**/ 505, /**/ diff --git a/src/viminfo.c b/src/viminfo.c index bb84726c8f..95ec55ebb3 100644 --- a/src/viminfo.c +++ b/src/viminfo.c @@ -435,6 +435,8 @@ write_viminfo_bufferlist(FILE *fp) fputs(_("\n# Buffer list:\n"), fp); FOR_ALL_BUFFERS(buf) { + size_t linelen; + if (buf->b_fname == NULL || !buf->b_p_bl || bt_quickfix(buf) @@ -445,8 +447,8 @@ write_viminfo_bufferlist(FILE *fp) if (max_buffers-- == 0) break; putc('%', fp); - home_replace(NULL, buf->b_ffname, line, MAXPATHL, TRUE); - vim_snprintf_add((char *)line, LINE_BUF_LEN, "\t%ld\t%d", + linelen = home_replace(NULL, buf->b_ffname, line, MAXPATHL, TRUE); + vim_snprintf((char *)line + linelen, LINE_BUF_LEN - linelen, "\t%ld\t%d", (long)buf->b_last_cursor.lnum, buf->b_last_cursor.col); viminfo_writestring(fp, line);