mirror of
https://github.com/neovim/neovim.git
synced 2026-08-27 09:31:47 +00:00
vim-patch:partial:9.1.0973: too many strlen() calls in fileio.c
Problem: too many strlen() calls in fileio.c
Solution: refactor fileio.c and remove calls to STRLEN(),
check for out-of-memory condition in buf_check_timestamp()
(John Marriott)
closes: vim/vim#16306
14ede1890f
Full port requires v8.2.0988 to update readdir_core().
Co-authored-by: John Marriott <basilisk@internode.on.net>
This commit is contained in:
@@ -329,10 +329,10 @@ int readfile(char *fname, char *sfname, linenr_T from, linenr_T lines_to_skip,
|
|||||||
}
|
}
|
||||||
// If the name is too long we might crash further on, quit here.
|
// If the name is too long we might crash further on, quit here.
|
||||||
if (fname != NULL && *fname != NUL) {
|
if (fname != NULL && *fname != NUL) {
|
||||||
size_t namelen = strlen(fname);
|
size_t fnamelen = strlen(fname);
|
||||||
|
|
||||||
// If the name is too long we might crash further on, quit here.
|
// If the name is too long we might crash further on, quit here.
|
||||||
if (namelen >= MAXPATHL) {
|
if (fnamelen >= MAXPATHL) {
|
||||||
filemess(curbuf, fname, _("Illegal file name"));
|
filemess(curbuf, fname, _("Illegal file name"));
|
||||||
msg_end();
|
msg_end();
|
||||||
msg_scroll = msg_save;
|
msg_scroll = msg_save;
|
||||||
@@ -342,7 +342,7 @@ int readfile(char *fname, char *sfname, linenr_T from, linenr_T lines_to_skip,
|
|||||||
// If the name ends in a path separator, we can't open it. Check here,
|
// 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
|
// because reading the file may actually work, but then creating the
|
||||||
// swap file may destroy it! Reported on MS-DOS and Win 95.
|
// swap file may destroy it! Reported on MS-DOS and Win 95.
|
||||||
if (after_pathsep(fname, fname + namelen)) {
|
if (after_pathsep(fname, fname + fnamelen)) {
|
||||||
if (!silent) {
|
if (!silent) {
|
||||||
filemess(curbuf, fname, _(msg_is_a_directory));
|
filemess(curbuf, fname, _(msg_is_a_directory));
|
||||||
}
|
}
|
||||||
@@ -1700,55 +1700,57 @@ failed:
|
|||||||
add_quoted_fname(IObuff, IOSIZE, curbuf, sfname);
|
add_quoted_fname(IObuff, IOSIZE, curbuf, sfname);
|
||||||
c = false;
|
c = false;
|
||||||
|
|
||||||
|
int buflen = (int)strlen(IObuff);
|
||||||
#ifdef UNIX
|
#ifdef UNIX
|
||||||
if (S_ISFIFO(perm)) { // fifo
|
if (S_ISFIFO(perm)) { // fifo
|
||||||
xstrlcat(IObuff, _("[fifo]"), IOSIZE);
|
buflen += snprintf(IObuff + buflen, (size_t)(IOSIZE - buflen), _("[fifo]"));
|
||||||
c = true;
|
c = true;
|
||||||
}
|
}
|
||||||
if (S_ISSOCK(perm)) { // or socket
|
if (S_ISSOCK(perm)) { // or socket
|
||||||
xstrlcat(IObuff, _("[socket]"), IOSIZE);
|
buflen += snprintf(IObuff + buflen, (size_t)(IOSIZE - buflen), _("[socket]"));
|
||||||
c = true;
|
c = true;
|
||||||
}
|
}
|
||||||
# ifdef OPEN_CHR_FILES
|
# ifdef OPEN_CHR_FILES
|
||||||
if (S_ISCHR(perm)) { // or character special
|
if (S_ISCHR(perm)) { // or character special
|
||||||
xstrlcat(IObuff, _("[character special]"), IOSIZE);
|
buflen += snprintf(IObuff + buflen, (size_t)(IOSIZE - buflen), _("[character special]"));
|
||||||
c = true;
|
c = true;
|
||||||
}
|
}
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
if (curbuf->b_p_ro) {
|
if (curbuf->b_p_ro) {
|
||||||
xstrlcat(IObuff, shortmess(SHM_RO) ? _("[RO]") : _("[readonly]"), IOSIZE);
|
buflen += snprintf(IObuff + buflen, (size_t)(IOSIZE - buflen), "%s",
|
||||||
|
shortmess(SHM_RO) ? _("[RO]") : _("[readonly]"));
|
||||||
c = true;
|
c = true;
|
||||||
}
|
}
|
||||||
if (read_no_eol_lnum) {
|
if (read_no_eol_lnum) {
|
||||||
xstrlcat(IObuff, _("[noeol]"), IOSIZE);
|
buflen += snprintf(IObuff + buflen, (size_t)(IOSIZE - buflen), _("[noeol]"));
|
||||||
c = true;
|
c = true;
|
||||||
}
|
}
|
||||||
if (ff_error == EOL_DOS) {
|
if (ff_error == EOL_DOS) {
|
||||||
xstrlcat(IObuff, _("[CR missing]"), IOSIZE);
|
buflen += snprintf(IObuff + buflen, (size_t)(IOSIZE - buflen), _("CR missing"));
|
||||||
c = true;
|
c = true;
|
||||||
}
|
}
|
||||||
if (split) {
|
if (split) {
|
||||||
xstrlcat(IObuff, _("[long lines split]"), IOSIZE);
|
buflen += snprintf(IObuff + buflen, (size_t)(IOSIZE - buflen), _("[long lines split]"));
|
||||||
c = true;
|
c = true;
|
||||||
}
|
}
|
||||||
if (notconverted) {
|
if (notconverted) {
|
||||||
xstrlcat(IObuff, _("[NOT converted]"), IOSIZE);
|
buflen += snprintf(IObuff + buflen, (size_t)(IOSIZE - buflen), _("[NOT converted]"));
|
||||||
c = true;
|
c = true;
|
||||||
} else if (converted) {
|
} else if (converted) {
|
||||||
xstrlcat(IObuff, _("[converted]"), IOSIZE);
|
buflen += snprintf(IObuff + buflen, (size_t)(IOSIZE - buflen), _("[converted]"));
|
||||||
c = true;
|
c = true;
|
||||||
}
|
}
|
||||||
if (conv_error != 0) {
|
if (conv_error != 0) {
|
||||||
snprintf(IObuff + strlen(IObuff), IOSIZE - strlen(IObuff),
|
snprintf(IObuff + buflen, (size_t)(IOSIZE - buflen),
|
||||||
_("[CONVERSION ERROR in line %" PRId64 "]"), (int64_t)conv_error);
|
_("[CONVERSION ERROR in line %" PRId64 "]"), (int64_t)conv_error);
|
||||||
c = true;
|
c = true;
|
||||||
} else if (illegal_byte > 0) {
|
} else if (illegal_byte > 0) {
|
||||||
snprintf(IObuff + strlen(IObuff), IOSIZE - strlen(IObuff),
|
snprintf(IObuff + buflen, (size_t)(IOSIZE - buflen),
|
||||||
_("[ILLEGAL BYTE in line %" PRId64 "]"), (int64_t)illegal_byte);
|
_("[ILLEGAL BYTE in line %" PRId64 "]"), (int64_t)illegal_byte);
|
||||||
c = true;
|
c = true;
|
||||||
} else if (error) {
|
} else if (error) {
|
||||||
xstrlcat(IObuff, _("[READ ERRORS]"), IOSIZE);
|
snprintf(IObuff + buflen, (size_t)(IOSIZE - buflen), _("[READ ERRORS]"));
|
||||||
c = true;
|
c = true;
|
||||||
}
|
}
|
||||||
if (msg_add_fileformat(fileformat)) {
|
if (msg_add_fileformat(fileformat)) {
|
||||||
@@ -2141,22 +2143,18 @@ bool msg_add_fileformat(int eol_type)
|
|||||||
/// Append line and character count to IObuff.
|
/// Append line and character count to IObuff.
|
||||||
void msg_add_lines(int insert_space, linenr_T lnum, off_T nchars)
|
void msg_add_lines(int insert_space, linenr_T lnum, off_T nchars)
|
||||||
{
|
{
|
||||||
char *p = IObuff + strlen(IObuff);
|
size_t len = strlen(IObuff);
|
||||||
|
|
||||||
if (insert_space) {
|
|
||||||
*p++ = ' ';
|
|
||||||
}
|
|
||||||
if (shortmess(SHM_LINES)) {
|
if (shortmess(SHM_LINES)) {
|
||||||
vim_snprintf(p, (size_t)(IOSIZE - (p - IObuff)), "%" PRId64 "L, %" PRId64 "B",
|
snprintf(IObuff + len, IOSIZE - len, "%s%" PRId64 "L, %" PRId64 "B",
|
||||||
(int64_t)lnum, (int64_t)nchars);
|
insert_space ? " " : "", (int64_t)lnum, (int64_t)nchars);
|
||||||
} else {
|
} else {
|
||||||
vim_snprintf(p, (size_t)(IOSIZE - (p - IObuff)),
|
len += (size_t)snprintf(IObuff + len, IOSIZE - len,
|
||||||
NGETTEXT("%" PRId64 " line, ", "%" PRId64 " lines, ", lnum),
|
NGETTEXT("%s%" PRId64 " line, ", "%s%" PRId64 " lines, ", lnum),
|
||||||
(int64_t)lnum);
|
insert_space ? " " : "", (int64_t)lnum);
|
||||||
p += strlen(p);
|
snprintf(IObuff + len, IOSIZE - len,
|
||||||
vim_snprintf(p, (size_t)(IOSIZE - (p - IObuff)),
|
NGETTEXT("%" PRId64 " byte", "%" PRId64 " bytes", nchars),
|
||||||
NGETTEXT("%" PRId64 " byte", "%" PRId64 " bytes", nchars),
|
(int64_t)nchars);
|
||||||
(int64_t)nchars);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2401,11 +2399,13 @@ char *modname(const char *fname, const char *ext, bool prepend_dot)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// the file name has at most BASENAMELEN characters.
|
// the file name has at most BASENAMELEN characters.
|
||||||
if (strlen(ptr) > BASENAMELEN) {
|
size_t ptrlen = fnamelen - (size_t)(ptr - retval);
|
||||||
ptr[BASENAMELEN] = NUL;
|
if (ptrlen > (unsigned)BASENAMELEN) {
|
||||||
|
ptrlen = BASENAMELEN;
|
||||||
|
ptr[ptrlen] = NUL;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *s = ptr + strlen(ptr);
|
char *s = ptr + ptrlen;
|
||||||
|
|
||||||
// Append the extension.
|
// Append the extension.
|
||||||
// ext can start with '.' and cannot exceed 3 more characters.
|
// ext can start with '.' and cannot exceed 3 more characters.
|
||||||
@@ -2414,7 +2414,7 @@ char *modname(const char *fname, const char *ext, bool prepend_dot)
|
|||||||
char *e;
|
char *e;
|
||||||
// Prepend the dot if needed.
|
// Prepend the dot if needed.
|
||||||
if (prepend_dot && *(e = path_tail(retval)) != '.') {
|
if (prepend_dot && *(e = path_tail(retval)) != '.') {
|
||||||
STRMOVE(e + 1, e);
|
memmove(e + 1, e, ((fnamelen + extlen) - (size_t)(e - retval)) + 1); // +1 for NUL
|
||||||
*e = '.';
|
*e = '.';
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2809,7 +2809,7 @@ static int move_lines(buf_T *frombuf, buf_T *tobuf)
|
|||||||
// Copy the lines in "frombuf" to "tobuf".
|
// Copy the lines in "frombuf" to "tobuf".
|
||||||
curbuf = tobuf;
|
curbuf = tobuf;
|
||||||
for (linenr_T lnum = 1; lnum <= frombuf->b_ml.ml_line_count; lnum++) {
|
for (linenr_T lnum = 1; lnum <= frombuf->b_ml.ml_line_count; lnum++) {
|
||||||
char *p = xstrdup(ml_get_buf(frombuf, lnum));
|
char *p = xmemdupz(ml_get_buf(frombuf, lnum), (size_t)ml_get_buf_len(frombuf, lnum));
|
||||||
if (ml_append(lnum - 1, p, 0, false) == FAIL) {
|
if (ml_append(lnum - 1, p, 0, false) == FAIL) {
|
||||||
xfree(p);
|
xfree(p);
|
||||||
retval = FAIL;
|
retval = FAIL;
|
||||||
@@ -2907,24 +2907,31 @@ int buf_check_timestamp(buf_T *buf)
|
|||||||
reload = RELOAD_NORMAL;
|
reload = RELOAD_NORMAL;
|
||||||
} else {
|
} else {
|
||||||
char *reason;
|
char *reason;
|
||||||
|
size_t reasonlen;
|
||||||
|
|
||||||
if (!file_info_ok) {
|
if (!file_info_ok) {
|
||||||
reason = "deleted";
|
reason = "deleted";
|
||||||
|
reasonlen = STRLEN_LITERAL("deleted");
|
||||||
} else if (bufIsChanged(buf)) {
|
} else if (bufIsChanged(buf)) {
|
||||||
reason = "conflict";
|
reason = "conflict";
|
||||||
|
reasonlen = STRLEN_LITERAL("conflict");
|
||||||
} else if (orig_size != buf->b_orig_size || buf_contents_changed(buf)) {
|
} else if (orig_size != buf->b_orig_size || buf_contents_changed(buf)) {
|
||||||
reason = "changed";
|
reason = "changed";
|
||||||
|
reasonlen = STRLEN_LITERAL("changed");
|
||||||
} else if (orig_mode != buf->b_orig_mode) {
|
} else if (orig_mode != buf->b_orig_mode) {
|
||||||
reason = "mode";
|
reason = "mode";
|
||||||
|
reasonlen = STRLEN_LITERAL("mode");
|
||||||
} else {
|
} else {
|
||||||
reason = "time";
|
reason = "time";
|
||||||
|
reasonlen = STRLEN_LITERAL("time");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Only give the warning if there are no FileChangedShell
|
// Only give the warning if there are no FileChangedShell
|
||||||
// autocommands.
|
// autocommands.
|
||||||
// Avoid being called recursively by setting "busy".
|
// Avoid being called recursively by setting "busy".
|
||||||
busy = true;
|
busy = true;
|
||||||
set_vim_var_string(VV_FCS_REASON, reason, -1);
|
set_vim_var_string(VV_FCS_REASON, reason, (int)reasonlen);
|
||||||
set_vim_var_string(VV_FCS_CHOICE, "", -1);
|
set_vim_var_string(VV_FCS_CHOICE, "", 0);
|
||||||
allbuf_lock++;
|
allbuf_lock++;
|
||||||
bool n = apply_autocmds(EVENT_FILECHANGEDSHELL, buf->b_fname, buf->b_fname, false, buf);
|
bool n = apply_autocmds(EVENT_FILECHANGEDSHELL, buf->b_fname, buf->b_fname, false, buf);
|
||||||
allbuf_lock--;
|
allbuf_lock--;
|
||||||
@@ -2990,16 +2997,16 @@ int buf_check_timestamp(buf_T *buf)
|
|||||||
if (!helpmesg) {
|
if (!helpmesg) {
|
||||||
mesg2 = "";
|
mesg2 = "";
|
||||||
}
|
}
|
||||||
const size_t tbuf_len = strlen(path) + strlen(mesg) + strlen(mesg2) + 2;
|
// +2 for either '\n' or "; " and +1 for NUL
|
||||||
char *const tbuf = xmalloc(tbuf_len);
|
const size_t tbufsize = strlen(path) + strlen(mesg) + strlen(mesg2) + 3;
|
||||||
snprintf(tbuf, tbuf_len, mesg, path);
|
char *const tbuf = xmalloc(tbufsize);
|
||||||
|
int tbuflen = snprintf(tbuf, tbufsize, mesg, path);
|
||||||
// Set warningmsg here, before the unimportant and output-specific
|
// Set warningmsg here, before the unimportant and output-specific
|
||||||
// mesg2 has been appended.
|
// mesg2 has been appended.
|
||||||
set_vim_var_string(VV_WARNINGMSG, tbuf, -1);
|
set_vim_var_string(VV_WARNINGMSG, tbuf, tbuflen);
|
||||||
if (can_reload) {
|
if (can_reload) {
|
||||||
if (*mesg2 != NUL) {
|
if (*mesg2 != NUL) {
|
||||||
xstrlcat(tbuf, "\n", tbuf_len - 1);
|
snprintf(tbuf + tbuflen, tbufsize - (size_t)tbuflen, "\n%s", mesg2);
|
||||||
xstrlcat(tbuf, mesg2, tbuf_len - 1);
|
|
||||||
}
|
}
|
||||||
switch (do_dialog(VIM_WARNING, _("Warning"), tbuf,
|
switch (do_dialog(VIM_WARNING, _("Warning"), tbuf,
|
||||||
_("&OK\n&Load File\nLoad File &and Options"),
|
_("&OK\n&Load File\nLoad File &and Options"),
|
||||||
@@ -3013,8 +3020,7 @@ int buf_check_timestamp(buf_T *buf)
|
|||||||
}
|
}
|
||||||
} else if (State > MODE_NORMAL_BUSY || (State & MODE_CMDLINE) || already_warned) {
|
} else if (State > MODE_NORMAL_BUSY || (State & MODE_CMDLINE) || already_warned) {
|
||||||
if (*mesg2 != NUL) {
|
if (*mesg2 != NUL) {
|
||||||
xstrlcat(tbuf, "; ", tbuf_len - 1);
|
snprintf(tbuf + tbuflen, tbufsize - (size_t)tbuflen, "; %s", mesg2);
|
||||||
xstrlcat(tbuf, mesg2, tbuf_len - 1);
|
|
||||||
}
|
}
|
||||||
emsg(tbuf);
|
emsg(tbuf);
|
||||||
retval = 2;
|
retval = 2;
|
||||||
@@ -3035,8 +3041,8 @@ int buf_check_timestamp(buf_T *buf)
|
|||||||
already_warned = true;
|
already_warned = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
xfree(path);
|
|
||||||
xfree(tbuf);
|
xfree(tbuf);
|
||||||
|
xfree(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (reload != RELOAD_NONE) {
|
if (reload != RELOAD_NONE) {
|
||||||
@@ -3390,8 +3396,10 @@ int delete_recursive(const char *name)
|
|||||||
char *exp = xstrdup(name);
|
char *exp = xstrdup(name);
|
||||||
garray_T ga;
|
garray_T ga;
|
||||||
if (readdir_core(&ga, exp, NULL, NULL) == OK) {
|
if (readdir_core(&ga, exp, NULL, NULL) == OK) {
|
||||||
|
int len = snprintf(NameBuff, MAXPATHL, "%s/", exp);
|
||||||
|
|
||||||
for (int i = 0; i < ga.ga_len; i++) {
|
for (int i = 0; i < ga.ga_len; i++) {
|
||||||
vim_snprintf(NameBuff, MAXPATHL, "%s/%s", exp, ((char **)ga.ga_data)[i]);
|
snprintf(NameBuff + len, MAXPATHL - (size_t)len, "%s", ((char **)ga.ga_data)[i]);
|
||||||
if (delete_recursive(NameBuff) != 0) {
|
if (delete_recursive(NameBuff) != 0) {
|
||||||
// Remember the failure but continue deleting any further
|
// Remember the failure but continue deleting any further
|
||||||
// entries.
|
// entries.
|
||||||
@@ -3497,8 +3505,12 @@ static bool vim_settempdir(char *tempdir)
|
|||||||
}
|
}
|
||||||
|
|
||||||
vim_FullName(tempdir, buf, MAXPATHL, false);
|
vim_FullName(tempdir, buf, MAXPATHL, false);
|
||||||
add_pathsep(buf);
|
size_t buflen = strlen(buf);
|
||||||
vim_tempdir = xstrdup(buf);
|
if (!after_pathsep(buf, buf + buflen)) {
|
||||||
|
strcpy(buf + buflen, PATHSEPSTR); // NOLINT(runtime/printf)
|
||||||
|
buflen += STRLEN_LITERAL(PATHSEPSTR);
|
||||||
|
}
|
||||||
|
vim_tempdir = xmemdupz(buf, buflen);
|
||||||
#ifdef HAVE_DIRFD_AND_FLOCK
|
#ifdef HAVE_DIRFD_AND_FLOCK
|
||||||
vim_opentempdir();
|
vim_opentempdir();
|
||||||
#endif
|
#endif
|
||||||
@@ -3525,8 +3537,8 @@ char *vim_tempname(void)
|
|||||||
// There is no need to check if the file exists, because we own the directory
|
// There is no need to check if the file exists, because we own the directory
|
||||||
// and nobody else creates a file in it.
|
// and nobody else creates a file in it.
|
||||||
char templ[TEMP_FILE_PATH_MAXLEN];
|
char templ[TEMP_FILE_PATH_MAXLEN];
|
||||||
snprintf(templ, TEMP_FILE_PATH_MAXLEN, "%s%" PRIu64, tempdir, temp_count++);
|
int itmplen = snprintf(templ, TEMP_FILE_PATH_MAXLEN, "%s%" PRIu64, tempdir, temp_count++);
|
||||||
return xstrdup(templ);
|
return xmemdupz(templ, (size_t)itmplen);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Tries matching a filename with a "pattern" ("prog" is NULL), or use the
|
/// Tries matching a filename with a "pattern" ("prog" is NULL), or use the
|
||||||
|
|||||||
Reference in New Issue
Block a user