diff --git a/src/fileio.c b/src/fileio.c index 41e5b5dbf7bea3..2f5710405eac3a 100644 --- a/src/fileio.c +++ b/src/fileio.c @@ -55,17 +55,23 @@ filemess( { int msg_scroll_save; int prev_msg_col = msg_col; + size_t len; if (msg_silent != 0) return; msg_add_fname(buf, name); // put file name in IObuff with quotes // If it's extremely long, truncate it. - if (STRLEN(IObuff) > IOSIZE - 100) - IObuff[IOSIZE - 100] = NUL; + len = STRLEN(IObuff); + if (len > IOSIZE - 100) + { + len = IOSIZE - 100; + IObuff[len] = NUL; + } // Avoid an over-long translation to cause trouble. - STRNCAT(IObuff, s, 99); + if (*s != NUL) + STRNCPY(IObuff + len, s, 99); /* * For the first message may have to start a new line. @@ -224,6 +230,7 @@ readfile( #ifdef FEAT_SODIUM int may_need_lseek = FALSE; #endif + size_t fnamelen = 0; curbuf->b_au_did_filetype = FALSE; // reset before triggering any autocommands @@ -336,10 +343,10 @@ readfile( if (fname != NULL && *fname != NUL) { - size_t namelen = STRLEN(fname); + fnamelen = STRLEN(fname); // If the name is too long we might crash further on, quit here. - if (namelen >= MAXPATHL) + if (fnamelen >= MAXPATHL) { filemess(curbuf, fname, (char_u *)_("Illegal file name"), 0); msg_end(); @@ -350,7 +357,7 @@ readfile( // If the name ends in a path separator, we can't open it. Check here, // because reading the file may actually work, but then creating the // swap file may destroy it! Reported on MS-DOS and Win 95. - if (after_pathsep(fname, fname + namelen)) + if (after_pathsep(fname, fname + fnamelen)) { filemess(curbuf, fname, (char_u *)_(msg_is_a_directory), 0); msg_end(); @@ -776,11 +783,13 @@ readfile( // Also write a message in the GUI window, if there is one. if (gui.in_use && !gui.dying && !gui.starting) { + size_t plen = STRLEN(_("Reading from stdin...")); + // make a copy, gui_write() may try to change it - p = vim_strsave((char_u *)_("Reading from stdin...")); + p = vim_strnsave((char_u *)_("Reading from stdin..."), plen); if (p != NULL) { - gui_write(p, (int)STRLEN(p)); + gui_write(p, (int)plen); vim_free(p); } } @@ -838,7 +847,7 @@ readfile( c = enc_utf8; if (!c && !read_stdin) { - fc = fname[STRLEN(fname) - 1]; + fc = fname[fnamelen - 1]; if (TOLOWER_ASC(fc) == 'x') { // Read the first line (and a bit more). Immediately rewind to @@ -1001,7 +1010,6 @@ readfile( converted = need_conversion(fenc); if (converted) { - // "ucs-bom" means we need to check the first bytes of the file // for a BOM. if (STRCMP(fenc, ENC_UCSBOM) == 0) @@ -2481,31 +2489,38 @@ readfile( if (!filtering && !(flags & READ_DUMMY)) { + int buflen; + msg_add_fname(curbuf, sfname); // fname in IObuff with quotes c = FALSE; + buflen = (int)STRLEN(IObuff); #ifdef UNIX if (S_ISFIFO(perm)) // fifo { - STRCAT(IObuff, _("[fifo]")); + buflen += vim_snprintf((char *)IObuff + buflen, IOSIZE - buflen, + _("[fifo]")); c = TRUE; } if (S_ISSOCK(perm)) // or socket { - STRCAT(IObuff, _("[socket]")); + buflen += vim_snprintf((char *)IObuff + buflen, IOSIZE - buflen, + _("[socket]")); c = TRUE; } # ifdef OPEN_CHR_FILES if (S_ISCHR(perm)) // or character special { - STRCAT(IObuff, _("[character special]")); + buflen += vim_snprintf((char *)IObuff + buflen, IOSIZE - buflen, + _("[character special]")); c = TRUE; } # endif #endif if (curbuf->b_p_ro) { - STRCAT(IObuff, shortmess(SHM_RO) ? _("[RO]") : _("[readonly]")); + buflen += vim_snprintf((char *)IObuff + buflen, IOSIZE - buflen, + "%s", shortmess(SHM_RO) ? _("[RO]") : _("[readonly]")); c = TRUE; } if (read_no_eol_lnum) @@ -2515,22 +2530,26 @@ readfile( } if (ff_error == EOL_DOS) { - STRCAT(IObuff, _("[CR missing]")); + buflen += vim_snprintf((char *)IObuff + buflen, IOSIZE - buflen, + _("CR missing")); c = TRUE; } if (split) { - STRCAT(IObuff, _("[long lines split]")); + buflen += vim_snprintf((char *)IObuff + buflen, IOSIZE - buflen, + _("[long lines split]")); c = TRUE; } if (notconverted) { - STRCAT(IObuff, _("[NOT converted]")); + buflen += vim_snprintf((char *)IObuff + buflen, IOSIZE - buflen, + _("[NOT converted]")); c = TRUE; } else if (converted) { - STRCAT(IObuff, _("[converted]")); + buflen += vim_snprintf((char *)IObuff + buflen, IOSIZE - buflen, + _("[converted]")); c = TRUE; } #ifdef FEAT_CRYPT @@ -2542,19 +2561,20 @@ readfile( #endif if (conv_error != 0) { - sprintf((char *)IObuff + STRLEN(IObuff), - _("[CONVERSION ERROR in line %ld]"), (long)conv_error); + vim_snprintf((char *)IObuff + buflen, IOSIZE - buflen, + _("[CONVERSION ERROR in line %ld]"), (long)conv_error); c = TRUE; } else if (illegal_byte > 0) { - sprintf((char *)IObuff + STRLEN(IObuff), - _("[ILLEGAL BYTE in line %ld]"), (long)illegal_byte); + vim_snprintf((char *)IObuff + buflen, IOSIZE - buflen, + _("[ILLEGAL BYTE in line %ld]"), (long)illegal_byte); c = TRUE; } else if (error) { - STRCAT(IObuff, _("[READ ERRORS]")); + vim_snprintf((char *)IObuff + buflen, IOSIZE - buflen, + _("[READ ERRORS]")); c = TRUE; } if (msg_add_fileformat(fileformat)) @@ -3162,22 +3182,17 @@ msg_add_lines( long lnum, off_T nchars) { - char_u *p; + int len = (int)STRLEN(IObuff); - p = IObuff + STRLEN(IObuff); - - if (insert_space) - *p++ = ' '; if (shortmess(SHM_LINES)) - vim_snprintf((char *)p, IOSIZE - (p - IObuff), - "%ldL, %lldB", lnum, (varnumber_T)nchars); + vim_snprintf((char *)IObuff + len, IOSIZE - (size_t)len, + "%s%ldL, %lldB", insert_space ? " " : "", lnum, (varnumber_T)nchars); else { - sprintf((char *)p, NGETTEXT("%ld line, ", "%ld lines, ", lnum), lnum); - p += STRLEN(p); - vim_snprintf((char *)p, IOSIZE - (p - IObuff), - NGETTEXT("%lld byte", "%lld bytes", nchars), - (varnumber_T)nchars); + len += vim_snprintf((char *)IObuff + len, IOSIZE - (size_t)len, + NGETTEXT("%s%ld line, ", "%s%ld lines, ", lnum), insert_space ? " " : "", lnum); + vim_snprintf((char *)IObuff + len, IOSIZE - (size_t)len, + NGETTEXT("%lld byte", "%lld bytes", nchars), (varnumber_T)nchars); } } @@ -3585,6 +3600,7 @@ buf_modname( char_u *s; char_u *e; char_u *ptr; + size_t ptrlen; int fnamelen, extlen; extlen = (int)STRLEN(ext); @@ -3642,10 +3658,14 @@ buf_modname( } // the file name has at most BASENAMELEN characters. - if (STRLEN(ptr) > (unsigned)BASENAMELEN) - ptr[BASENAMELEN] = '\0'; + ptrlen = (size_t)(fnamelen - (ptr - retval)); + if (ptrlen > (unsigned)BASENAMELEN) + { + ptrlen = BASENAMELEN; + ptr[ptrlen] = NUL; + } - s = ptr + STRLEN(ptr); + s = ptr + ptrlen; /* * For 8.3 file names we may have to reduce the length. @@ -3685,7 +3705,7 @@ buf_modname( * If the extension doesn't start with '.', and there already is an * extension, it may need to be truncated */ - else if ((int)STRLEN(e) + extlen > 4) + else if ((int)(ptrlen - (e - retval)) + extlen > 4) s = e + 4 - extlen; } #ifdef MSWIN @@ -3703,13 +3723,12 @@ buf_modname( * ext can start with '.' and cannot exceed 3 more characters. */ STRCPY(s, ext); - /* * Prepend the dot. */ if (prepend_dot && !shortname && *(e = gettail(retval)) != '.') { - STRMOVE(e + 1, e); + mch_memmove(e + 1, e, (size_t)(((fnamelen + extlen) - (e - retval)) + 1)); // +1 for NUL *e = '.'; } @@ -4111,7 +4130,7 @@ move_lines(buf_T *frombuf, buf_T *tobuf) curbuf = tobuf; for (lnum = 1; lnum <= frombuf->b_ml.ml_line_count; ++lnum) { - p = vim_strsave(ml_get_buf(frombuf, lnum, FALSE)); + p = vim_strnsave(ml_get_buf(frombuf, lnum, FALSE), ml_get_buf_len(frombuf, lnum)); if (p == NULL || ml_append(lnum - 1, p, 0, FALSE) == FAIL) { vim_free(p); @@ -4154,8 +4173,6 @@ buf_check_timestamp( stat_T st; int stat_res; int retval = 0; - char_u *path; - char *tbuf; char *mesg = NULL; char *mesg2 = ""; int helpmesg = FALSE; @@ -4164,7 +4181,6 @@ buf_check_timestamp( RELOAD_NORMAL, RELOAD_DETECT } reload = RELOAD_NONE; - char *reason; #if defined(FEAT_CON_DIALOG) || defined(FEAT_GUI_DIALOG) int can_reload = FALSE; #endif @@ -4175,9 +4191,6 @@ buf_check_timestamp( #endif static int busy = FALSE; int n; -#ifdef FEAT_EVAL - char_u *s; -#endif bufref_T bufref; set_bufref(&bufref, buf); @@ -4242,21 +4255,51 @@ buf_check_timestamp( reload = RELOAD_NORMAL; else { + char *reason; +#ifdef FEAT_EVAL + size_t reasonlen; +#endif + if (stat_res < 0) + { reason = "deleted"; +#ifdef FEAT_EVAL + reasonlen = STRLEN_LITERAL("deleted"); +#endif + } else if (bufIsChanged(buf)) + { reason = "conflict"; +#ifdef FEAT_EVAL + reasonlen = STRLEN_LITERAL("conflict"); +#endif + } /* * Check if the file contents really changed to avoid giving a * warning when only the timestamp was set (e.g., checked out of * CVS). Always warn when the buffer was changed. */ else if (orig_size != buf->b_orig_size || buf_contents_changed(buf)) + { reason = "changed"; +#ifdef FEAT_EVAL + reasonlen = STRLEN_LITERAL("changed"); +#endif + } else if (orig_mode != buf->b_orig_mode) + { reason = "mode"; +#ifdef FEAT_EVAL + reasonlen = STRLEN_LITERAL("mode"); +#endif + } else + { reason = "time"; +#ifdef FEAT_EVAL + reasonlen = STRLEN_LITERAL("time"); +#endif + } /* * Only give the warning if there are no FileChangedShell @@ -4265,8 +4308,8 @@ buf_check_timestamp( */ busy = TRUE; #ifdef FEAT_EVAL - set_vim_var_string(VV_FCS_REASON, (char_u *)reason, -1); - set_vim_var_string(VV_FCS_CHOICE, (char_u *)"", -1); + set_vim_var_string(VV_FCS_REASON, (char_u *)reason, reasonlen); + set_vim_var_string(VV_FCS_CHOICE, (char_u *)"", 0); #endif ++allbuf_lock; n = apply_autocmds(EVENT_FILECHANGEDSHELL, @@ -4278,7 +4321,7 @@ buf_check_timestamp( if (!bufref_valid(&bufref)) emsg(_(e_filechangedshell_autocommand_deleted_buffer)); #ifdef FEAT_EVAL - s = get_vim_var_str(VV_FCS_CHOICE); + char_u *s = get_vim_var_str(VV_FCS_CHOICE); if (STRCMP(s, "reload") == 0 && *reason != 'd') reload = RELOAD_NORMAL; else if (STRCMP(s, "edit") == 0) @@ -4343,80 +4386,86 @@ buf_check_timestamp( if (mesg != NULL) { + char_u *path; + path = home_replace_save(buf, buf->b_fname); if (path != NULL) { + size_t tbufsize; + char *tbuf; + if (!helpmesg) mesg2 = ""; - tbuf = alloc(STRLEN(path) + STRLEN(mesg) + STRLEN(mesg2) + 2); - sprintf(tbuf, mesg, path); + tbufsize = STRLEN(mesg) + STRLEN(path) + 2 + STRLEN(mesg2) + 1; // +2 for either '\n' or "; " + // and +1 for NUL + tbuf = alloc(tbufsize); + if (tbuf != NULL) + { + int tbuflen; + + tbuflen = vim_snprintf(tbuf, tbufsize, mesg, path); #ifdef FEAT_EVAL - // Set warningmsg here, before the unimportant and output-specific - // mesg2 has been appended. - set_vim_var_string(VV_WARNINGMSG, (char_u *)tbuf, -1); + // Set warningmsg here, before the unimportant and output-specific + // mesg2 has been appended. + set_vim_var_string(VV_WARNINGMSG, (char_u *)tbuf, tbuflen); #endif #if defined(FEAT_CON_DIALOG) || defined(FEAT_GUI_DIALOG) - if (can_reload) - { - if (*mesg2 != NUL) - { - STRCAT(tbuf, "\n"); - STRCAT(tbuf, mesg2); - } - switch (do_dialog(VIM_WARNING, (char_u *)_("Warning"), - (char_u *)tbuf, - (char_u *)_("&OK\n&Load File\nLoad File &and Options"), - 1, NULL, TRUE)) + if (can_reload) { - case 2: - reload = RELOAD_NORMAL; - break; - case 3: - reload = RELOAD_DETECT; - break; + if (*mesg2 != NUL) + vim_snprintf(tbuf + tbuflen, tbufsize - tbuflen, "\n%s", mesg2); + switch (do_dialog(VIM_WARNING, (char_u *)_("Warning"), + (char_u *)tbuf, + (char_u *)_("&OK\n&Load File\nLoad File &and Options"), + 1, NULL, TRUE)) + { + case 2: + reload = RELOAD_NORMAL; + break; + case 3: + reload = RELOAD_DETECT; + break; + } } - } - else + else #endif - if (State > MODE_NORMAL_BUSY || (State & MODE_CMDLINE) - || already_warned) - { - if (*mesg2 != NUL) + if (State > MODE_NORMAL_BUSY || (State & MODE_CMDLINE) + || already_warned) { - STRCAT(tbuf, "; "); - STRCAT(tbuf, mesg2); + if (*mesg2 != NUL) + vim_snprintf(tbuf + tbuflen, tbufsize - tbuflen, "; %s", mesg2); + emsg(tbuf); + retval = 2; } - emsg(tbuf); - retval = 2; - } - else - { - if (!autocmd_busy) + else { - msg_start(); - msg_puts_attr(tbuf, HL_ATTR(HLF_E) + MSG_HIST); - if (*mesg2 != NUL) - msg_puts_attr(mesg2, HL_ATTR(HLF_W) + MSG_HIST); - msg_clr_eos(); - (void)msg_end(); - if (emsg_silent == 0 && !in_assert_fails) + if (!autocmd_busy) { - out_flush(); -#ifdef FEAT_GUI - if (!focus) -#endif - // give the user some time to think about it - ui_delay(1004L, TRUE); - - // don't redraw and erase the message - redraw_cmdline = FALSE; + msg_start(); + msg_puts_attr(tbuf, HL_ATTR(HLF_E) + MSG_HIST); + if (*mesg2 != NUL) + msg_puts_attr(mesg2, HL_ATTR(HLF_W) + MSG_HIST); + msg_clr_eos(); + (void)msg_end(); + if (emsg_silent == 0 && !in_assert_fails) + { + out_flush(); + #ifdef FEAT_GUI + if (!focus) + #endif + // give the user some time to think about it + ui_delay(1004L, TRUE); + + // don't redraw and erase the message + redraw_cmdline = FALSE; + } } + already_warned = TRUE; } - already_warned = TRUE; } - vim_free(path); vim_free(tbuf); + vim_free(path); } } @@ -4696,19 +4745,19 @@ getftypewfd(WIN32_FIND_DATAW *wfd) { if (tag == IO_REPARSE_TAG_MOUNT_POINT) return (char_u*)"junction"; - else if (tag == IO_REPARSE_TAG_SYMLINK) + if (tag == IO_REPARSE_TAG_SYMLINK) { if (flag & FILE_ATTRIBUTE_DIRECTORY) return (char_u*)"linkd"; - else - return (char_u*)"link"; + + return (char_u*)"link"; } return (char_u*)"reparse"; // unknown reparse point type } if (flag & FILE_ATTRIBUTE_DIRECTORY) return (char_u*)"dir"; - else - return (char_u*)"file"; + + return (char_u*)"file"; } static dict_T * @@ -4793,7 +4842,6 @@ create_readdirex_item(char_u *path, char_u *name) ret = mch_stat(p, &st); if (ret < 0) q = (char_u*)"link"; - } vim_free(p); @@ -4876,10 +4924,10 @@ compare_readdirex_item(const void *p1, const void *p2) name2 = dict_get_string(*(dict_T**)p2, "name", FALSE); if (readdirex_sort == READDIR_SORT_BYTE) return STRCMP(name1, name2); - else if (readdirex_sort == READDIR_SORT_IC) + if (readdirex_sort == READDIR_SORT_IC) return STRICMP(name1, name2); - else - return STRCOLL(name1, name2); + + return STRCOLL(name1, name2); } static int @@ -4887,10 +4935,10 @@ compare_readdir_item(const void *s1, const void *s2) { if (readdirex_sort == READDIR_SORT_BYTE) return STRCMP(*(char **)s1, *(char **)s2); - else if (readdirex_sort == READDIR_SORT_IC) + if (readdirex_sort == READDIR_SORT_IC) return STRICMP(*(char **)s1, *(char **)s2); - else - return STRCOLL(*(char **)s1, *(char **)s2); + + return STRCOLL(*(char **)s1, *(char **)s2); } #endif @@ -4919,6 +4967,7 @@ readdir_core( HANDLE hFind = INVALID_HANDLE_VALUE; WIN32_FIND_DATAW wfd; WCHAR *wn = NULL; // UTF-16 name, NULL when not used. + char_u *p_end; # else DIR *dirp; struct dirent *dp; @@ -4944,11 +4993,11 @@ readdir_core( if (buf == NULL) return FAIL; STRNCPY(buf, path, MAXPATHL-5); - p = buf + STRLEN(buf); + p = p_end = buf + STRLEN(buf); MB_PTR_BACK(buf, p); if (*p == '\\' || *p == '/') - *p = NUL; - STRCAT(p, "\\*"); + p_end = p; + STRCPY(p_end, "\\*"); wn = enc_to_utf16(buf, NULL); if (wn != NULL) @@ -5118,9 +5167,6 @@ readdir_core( delete_recursive(char_u *name) { int result = 0; - int i; - char_u *exp; - garray_T ga; // A symbolic link to a directory itself is deleted, not the directory it // points to. @@ -5132,15 +5178,19 @@ delete_recursive(char_u *name) # endif ) { - exp = vim_strsave(name); + char_u *exp = vim_strsave(name); + garray_T ga; + if (exp == NULL) return -1; if (readdir_core(&ga, exp, FALSE, NULL, NULL, READDIR_SORT_NONE) == OK) { + int len = vim_snprintf((char *)NameBuff, MAXPATHL, "%s/", exp); + int i; + for (i = 0; i < ga.ga_len; ++i) { - vim_snprintf((char *)NameBuff, MAXPATHL, "%s/%s", exp, - ((char_u **)ga.ga_data)[i]); + vim_snprintf((char *)NameBuff + len, MAXPATHL - len, "%s", ((char_u **)ga.ga_data)[i]); if (delete_recursive(NameBuff) != 0) // Remember the failure but continue deleting any further // entries. @@ -5226,6 +5276,7 @@ vim_deltempdir(void) vim_settempdir(char_u *tempdir) { char_u *buf; + size_t buflen; buf = alloc(MAXPATHL + 2); if (buf == NULL) @@ -5233,8 +5284,13 @@ vim_settempdir(char_u *tempdir) if (vim_FullName(tempdir, buf, MAXPATHL, FALSE) == FAIL) STRCPY(buf, tempdir); - add_pathsep(buf); - vim_tempdir = vim_strsave(buf); + buflen = STRLEN(buf); + if (!after_pathsep(buf, buf + buflen)) + { + STRCPY(buf + buflen, PATHSEPSTR); + buflen += STRLEN_LITERAL(PATHSEPSTR); + } + vim_tempdir = vim_strnsave(buf, buflen); # if defined(UNIX) && defined(HAVE_FLOCK) && defined(HAVE_DIRFD) vim_opentempdir(); # endif @@ -5286,7 +5342,6 @@ vim_tempname( for (i = 0; i < (int)ARRAY_LENGTH(tempdirs); ++i) { # ifndef HAVE_MKDTEMP - size_t itmplen; long nr; long off; # endif @@ -5296,8 +5351,14 @@ vim_tempname( expand_env((char_u *)tempdirs[i], itmp, TEMPNAMELEN - 20); if (itmp[0] != '$' && mch_isdir(itmp)) { + size_t itmplen = STRLEN(itmp); + // directory exists - add_pathsep(itmp); + if (!after_pathsep(itmp, itmp + itmplen)) + { + STRCPY(itmp + itmplen, PATHSEPSTR); + itmplen += STRLEN_LITERAL(PATHSEPSTR); + } # ifdef HAVE_MKDTEMP { @@ -5307,7 +5368,8 @@ vim_tempname( mode_t umask_save = umask(077); # endif // Leave room for filename - STRCAT(itmp, "vXXXXXX"); + STRCPY(itmp + itmplen, "vXXXXXX"); + itmplen += STRLEN_LITERAL("vXXXXXX"); if (mkdtemp((char *)itmp) != NULL) vim_settempdir(itmp); # if defined(UNIX) || defined(VMS) @@ -5320,7 +5382,6 @@ vim_tempname( // otherwise it doesn't matter. The use of mkdir() avoids any // security problems because of the predictable number. nr = (mch_get_pid() + (long)time(NULL)) % 1000000L; - itmplen = STRLEN(itmp); // Try up to 10000 different values until we find a name that // doesn't exist. @@ -5331,7 +5392,7 @@ vim_tempname( mode_t umask_save; # endif - sprintf((char *)itmp + itmplen, "v%ld", nr + off); + vim_snprintf((char *)itmp + itmplen, sizeof(itmp) - itmplen, "v%ld", nr + off); # ifndef EEXIST // If mkdir() does not set errno to EEXIST, check for // existing file here. There is a race condition then, @@ -5372,20 +5433,20 @@ vim_tempname( { // There is no need to check if the file exists, because we own the // directory and nobody else creates a file in it. - sprintf((char *)itmp, "%s%ld", vim_tempdir, temp_count++); - return vim_strsave(itmp); + int itmplen = vim_snprintf((char *)itmp, sizeof(itmp), "%s%ld", vim_tempdir, temp_count++); + return vim_strnsave(itmp, (size_t)itmplen); } return NULL; #else // TEMPDIRNAMES + char_u *p; # ifdef MSWIN WCHAR wszTempFile[_MAX_PATH + 1]; WCHAR buf4[4]; WCHAR *chartab = L"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; char_u *retval; - char_u *p; char_u *shname; long i; @@ -5405,7 +5466,7 @@ vim_tempname( if (GetTempFileNameW(wszTempFile, buf4, 0, itmp) == 0) return NULL; if (!keep) - // GetTempFileName() will create the file, we don't want that + // GetTempFileNameW() will create the file, we don't want that (void)DeleteFileW(itmp); // Backslashes in a temp file name cause problems when filtering with @@ -5422,34 +5483,32 @@ vim_tempname( return retval; # else // MSWIN + int itmplen; # ifdef USE_TMPNAM - char_u *p; - // tmpnam() will make its own name p = tmpnam((char *)itmp); if (p == NULL || *p == NUL) return NULL; # else - char_u *p; # ifdef VMS_TEMPNAM // mktemp() is not working on VMS. It seems to be // a do-nothing function. Therefore we use tempnam(). - sprintf((char *)itmp, "VIM%c", extra_char); + vim_snprintf((char *)itmp, sizeof(itmp), "VIM%c", extra_char); p = (char_u *)tempnam("tmp:", (char *)itmp); if (p != NULL) { // VMS will use '.LIS' if we don't explicitly specify an extension, // and VIM will then be unable to find the file later - STRCPY(itmp, p); - STRCAT(itmp, ".txt"); + itmplen = vim_snprintf((char *)itmp, sizeof(itmp), "%s.txt", p); free(p); } else return NULL; # else STRCPY(itmp, TEMPNAME); + itmplen = STRLEN_LITERAL(TEMPNAME); if ((p = vim_strchr(itmp, '?')) != NULL) *p = extra_char; if (mktemp((char *)itmp) == NULL) @@ -5457,7 +5516,7 @@ vim_tempname( # endif # endif - return vim_strsave(itmp); + return vim_strnsave(itmp, (size_t)itmplen); # endif // MSWIN #endif // TEMPDIRNAMES } diff --git a/src/version.c b/src/version.c index 18a736c6e8f6b4..f37ad9418e1135 100644 --- a/src/version.c +++ b/src/version.c @@ -704,6 +704,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 973, /**/ 972, /**/