diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c index 94322f1720..e9e030a786 100644 --- a/src/nvim/ex_cmds.c +++ b/src/nvim/ex_cmds.c @@ -1662,7 +1662,13 @@ void append_redir(char *const buf, const size_t buflen, const char *const opt, } if (p != NULL) { *end = ' '; // not really needed? Not with sh, ksh or bash + +// This looks incredibly suss because it is: we are allowing a user option to +// define a snprintf format string. Such code should normally not be written. +// The validitiy of these option values are checked in `did_set_shellpipe_redir` + PRAGMA_DIAG_PUSH_IGNORE_MISSING_FORMAT_ATTRIBUTE; vim_snprintf(end + 1, (size_t)((ptrdiff_t)buflen - (end + 1 - buf)), opt, fname); + PRAGMA_DIAG_POP; } else { vim_snprintf(end, (size_t)((ptrdiff_t)buflen - (end - buf)), " %s %s", opt, fname); } @@ -2023,8 +2029,7 @@ int check_overwrite(exarg_T *eap, buf_T *buf, char *fname, char *ffname, bool ot #endif if (p_confirm || (cmdmod.cmod_flags & CMOD_CONFIRM)) { char buff[DIALOG_MSG_SIZE]; - - dialog_msg(buff, _("Overwrite existing file \"%s\"?"), fname); + snprintf(buff, sizeof buff, _("Overwrite existing file \"%s\"?"), fname); if (vim_dialog_yesno(VIM_QUESTION, NULL, buff, 2) != VIM_YES) { return FAIL; } @@ -2058,9 +2063,9 @@ int check_overwrite(exarg_T *eap, buf_T *buf, char *fname, char *ffname, bool ot if (p_confirm || (cmdmod.cmod_flags & CMOD_CONFIRM)) { char buff[DIALOG_MSG_SIZE]; - dialog_msg(buff, - _("Swap file \"%s\" exists, overwrite anyway?"), - swapname); + vim_snprintf(buff, sizeof buff, + _("Swap file \"%s\" exists, overwrite anyway?"), + swapname); if (vim_dialog_yesno(VIM_QUESTION, NULL, buff, 2) != VIM_YES) { xfree(swapname); @@ -2184,15 +2189,16 @@ static int check_readonly(int *forceit, buf_T *buf) if ((p_confirm || (cmdmod.cmod_flags & CMOD_CONFIRM)) && buf->b_fname != NULL) { char buff[DIALOG_MSG_SIZE]; + const char *fname = buf->b_fname ? buf->b_fname : _("Untitled"); if (buf->b_p_ro) { - dialog_msg(buff, - _("'readonly' option is set for \"%s\".\nDo you wish to write anyway?"), - buf->b_fname); + snprintf(buff, sizeof buff, + _("'readonly' option is set for \"%s\".\nDo you wish to write anyway?"), + fname); } else { - dialog_msg(buff, - _("File permissions of \"%s\" are read-only.\nIt may still be possible to " - "write it.\nDo you wish to try?"), - buf->b_fname); + snprintf(buff, sizeof buff, + _("File permissions of \"%s\" are read-only.\nIt may still be possible to " + "write it.\nDo you wish to try?"), + fname); } if (vim_dialog_yesno(VIM_QUESTION, NULL, buff, 2) == VIM_YES) { diff --git a/src/nvim/ex_cmds2.c b/src/nvim/ex_cmds2.c index 1a36995b6e..f90cf0d144 100644 --- a/src/nvim/ex_cmds2.c +++ b/src/nvim/ex_cmds2.c @@ -203,7 +203,8 @@ void dialog_changed(buf_T *buf, bool checkall) .forceit = false, }; - dialog_msg(buff, _("Save changes to \"%s\"?"), buf->b_fname); + const char *fname = buf->b_fname ? buf->b_fname : _("Untitled"); + snprintf(buff, sizeof buff, _("Save changes to \"%s\"?"), fname); if (checkall) { ret = vim_dialog_yesnoallcancel(VIM_QUESTION, NULL, buff, 1); } else { @@ -267,8 +268,8 @@ bool dialog_close_terminal(buf_T *buf) { char buff[DIALOG_MSG_SIZE]; - dialog_msg(buff, _("Close \"%s\"?"), - (buf->b_fname != NULL) ? buf->b_fname : "?"); + snprintf(buff, sizeof buff, _("Close \"%s\"?"), + (buf->b_fname != NULL) ? buf->b_fname : "?"); int ret = vim_dialog_yesnocancel(VIM_QUESTION, NULL, buff, 1); diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c index 811ab1d479..425760f4ec 100644 --- a/src/nvim/ex_docmd.c +++ b/src/nvim/ex_docmd.c @@ -8041,16 +8041,6 @@ static void ex_shada(exarg_T *eap) p_shada = save_shada; } -/// Make a dialog message in "buff[DIALOG_MSG_SIZE]". -/// "format" must contain "%s". -void dialog_msg(char *buff, char *format, char *fname) -{ - if (fname == NULL) { - fname = _("Untitled"); - } - vim_snprintf(buff, DIALOG_MSG_SIZE, format, fname); -} - static TriState filetype_detect = kNone; static TriState filetype_plugin = kNone; static TriState filetype_indent = kNone; diff --git a/src/nvim/ex_docmd.h b/src/nvim/ex_docmd.h index 369a6dcc5f..7ea2cf1133 100644 --- a/src/nvim/ex_docmd.h +++ b/src/nvim/ex_docmd.h @@ -28,7 +28,7 @@ enum { // Whether a command index indicates a user command. #define IS_USER_CMDIDX(idx) ((int)(idx) < 0) -enum { DIALOG_MSG_SIZE = 1000, }; ///< buffer size for dialog_msg() +enum { DIALOG_MSG_SIZE = 1000, }; ///< buffer size for dialog messages /// Structure used to save the current state. Used when executing Normal mode /// commands while in any other mode. diff --git a/src/nvim/macros_defs.h b/src/nvim/macros_defs.h index 5e0252bf04..3a40fe3705 100644 --- a/src/nvim/macros_defs.h +++ b/src/nvim/macros_defs.h @@ -145,6 +145,9 @@ # define PRAGMA_DIAG_PUSH_IGNORE_MISSING_PROTOTYPES \ _Pragma("clang diagnostic push") \ _Pragma("clang diagnostic ignored \"-Wmissing-prototypes\"") +# define PRAGMA_DIAG_PUSH_IGNORE_MISSING_FORMAT_ATTRIBUTE \ + _Pragma("clang diagnostic push") \ + _Pragma("clang diagnostic ignored \"-Wmissing-format-attribute\"") # ifdef HAVE_WIMPLICIT_FALLTHROUGH_FLAG # define PRAGMA_DIAG_PUSH_IGNORE_IMPLICIT_FALLTHROUGH \ _Pragma("clang diagnostic push") \ @@ -159,6 +162,8 @@ # define PRAGMA_DIAG_PUSH_IGNORE_MISSING_PROTOTYPES \ _Pragma("GCC diagnostic push") \ _Pragma("GCC diagnostic ignored \"-Wmissing-prototypes\"") +# define PRAGMA_DIAG_PUSH_IGNORE_MISSING_FORMAT_ATTRIBUTE \ + _Pragma("GCC diagnostic push") # ifdef HAVE_WIMPLICIT_FALLTHROUGH_FLAG # define PRAGMA_DIAG_PUSH_IGNORE_IMPLICIT_FALLTHROUGH \ _Pragma("GCC diagnostic push") \ @@ -171,6 +176,7 @@ _Pragma("GCC diagnostic pop") #else # define PRAGMA_DIAG_PUSH_IGNORE_MISSING_PROTOTYPES +# define PRAGMA_DIAG_PUSH_IGNORE_MISSING_FORMAT_ATTRIBUTE # define PRAGMA_DIAG_PUSH_IGNORE_IMPLICIT_FALLTHROUGH # define PRAGMA_DIAG_POP #endif diff --git a/src/nvim/optionstr.c b/src/nvim/optionstr.c index d16d2b18c0..789450021b 100644 --- a/src/nvim/optionstr.c +++ b/src/nvim/optionstr.c @@ -2306,12 +2306,15 @@ static const struct chars_tab lcs_tab[] = { #undef CHARSTAB_ENTRY -static char *field_value_err(char *errbuf, size_t errbuflen, const char *fmt, const char *field) +static char *field_value_err(char *errbuf, size_t errbuflen, const char *fmt, ...) { if (errbuf == NULL) { return ""; } - vim_snprintf(errbuf, errbuflen, _(fmt), field); + va_list arglist; + va_start(arglist, fmt); + vim_vsnprintf(errbuf, errbuflen, _(fmt), arglist); + va_end(arglist); return errbuf; }