diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/nvim/ex_cmds.c | 21 | ||||
-rw-r--r-- | src/nvim/file_search.c | 3 | ||||
-rw-r--r-- | src/nvim/globals.h | 1 | ||||
-rw-r--r-- | src/nvim/memory.c | 27 | ||||
-rw-r--r-- | src/nvim/os/os_defs.h | 2 | ||||
-rw-r--r-- | src/nvim/path.c | 8 | ||||
-rw-r--r-- | src/nvim/vim.h | 1 |
7 files changed, 52 insertions, 11 deletions
diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c index cf711552be..431b608bef 100644 --- a/src/nvim/ex_cmds.c +++ b/src/nvim/ex_cmds.c @@ -4977,8 +4977,12 @@ static void helptags_one(char_u *dir, char_u *ext, char_u *tagfname, // Find all *.txt files. size_t dirlen = STRLCPY(NameBuff, dir, sizeof(NameBuff)); - STRCAT(NameBuff, "/**/*"); // NOLINT - STRCAT(NameBuff, ext); + if (dirlen >= MAXPATHL + || STRLCAT(NameBuff, "/**/*", sizeof(NameBuff)) >= MAXPATHL // NOLINT + || STRLCAT(NameBuff, ext, sizeof(NameBuff)) >= MAXPATHL) { + EMSG(_(e_pathtoolong)); + return; + } // Note: We cannot just do `&NameBuff` because it is a statically sized array // so `NameBuff == &NameBuff` according to C semantics. @@ -4995,9 +4999,12 @@ static void helptags_one(char_u *dir, char_u *ext, char_u *tagfname, * Open the tags file for writing. * Do this before scanning through all the files. */ - STRLCPY(NameBuff, dir, sizeof(NameBuff)); + memcpy(NameBuff, dir, dirlen + 1); add_pathsep((char *)NameBuff); - STRNCAT(NameBuff, tagfname, sizeof(NameBuff) - dirlen - 2); + if (STRLCAT(NameBuff, tagfname, sizeof(NameBuff)) >= MAXPATHL) { + EMSG(_(e_pathtoolong)); + return; + } fd_tags = mch_fopen((char *)NameBuff, "w"); if (fd_tags == NULL) { EMSG2(_("E152: Cannot open %s for writing"), NameBuff); @@ -5172,7 +5179,11 @@ static void do_helptags(char_u *dirname, bool add_help_tags) // Get a list of all files in the help directory and in subdirectories. STRLCPY(NameBuff, dirname, sizeof(NameBuff)); add_pathsep((char *)NameBuff); - STRCAT(NameBuff, "**"); + if (STRLCAT(NameBuff, "**", MAXPATHL) >= MAXPATHL) { + EMSG(_(e_pathtoolong)); + xfree(dirname); + return; + } // Note: We cannot just do `&NameBuff` because it is a statically sized array // so `NameBuff == &NameBuff` according to C semantics. diff --git a/src/nvim/file_search.c b/src/nvim/file_search.c index 03cb504f17..122cea7466 100644 --- a/src/nvim/file_search.c +++ b/src/nvim/file_search.c @@ -191,9 +191,6 @@ typedef struct ff_search_ctx_T { # include "file_search.c.generated.h" #endif -static char_u e_pathtoolong[] = N_("E854: path too long for completion"); - - /* * Initialization routine for vim_findfile(). * diff --git a/src/nvim/globals.h b/src/nvim/globals.h index e3c84cb852..2c6c0025dd 100644 --- a/src/nvim/globals.h +++ b/src/nvim/globals.h @@ -1215,6 +1215,7 @@ EXTERN char_u e_invalidreg[] INIT(= N_("E850: Invalid register name")); EXTERN char_u e_dirnotf[] INIT(= N_( "E919: Directory not found in '%s': \"%s\"")); EXTERN char_u e_unsupportedoption[] INIT(= N_("E519: Option not supported")); +EXTERN char_u e_pathtoolong[] INIT(= N_("E854: path too long for completion")); EXTERN char top_bot_msg[] INIT(= N_("search hit TOP, continuing at BOTTOM")); diff --git a/src/nvim/memory.c b/src/nvim/memory.c index 92ead873ae..6408ac1664 100644 --- a/src/nvim/memory.c +++ b/src/nvim/memory.c @@ -389,6 +389,33 @@ size_t xstrlcpy(char *restrict dst, const char *restrict src, size_t size) return ret; } +/// xstrlcat - Appends string src to the end of dst. +/// +/// Compatible with *BSD strlcat: Appends at most (dstsize - strlen(dst) - 1) +/// characters. dst will be NUL-terminated. +/// +/// Note: Replaces `vim_strcat`. +/// +/// @param dst Where to copy the string to +/// @param src Where to copy the string from +/// @param dstsize Size of destination buffer, must be greater than 0 +/// @return strlen(src) + MIN(dstsize, strlen(initial dst)). +/// If retval >= dstsize, truncation occurs. +size_t xstrlcat(char *restrict dst, const char *restrict src, size_t dstsize) + FUNC_ATTR_NONNULL_ALL +{ + assert(dstsize > 0); + size_t srclen = strlen(src); + size_t dstlen = strlen(dst); + size_t ret = srclen + dstlen; // Total string length (excludes NUL) + if (srclen) { + size_t len = (ret >= dstsize) ? dstsize - 1 : ret; + memcpy(dst + dstlen, src, len - dstlen); + dst[len] = '\0'; + } + return ret; // Does not include NUL. +} + /// strdup() wrapper /// /// @see {xmalloc} diff --git a/src/nvim/os/os_defs.h b/src/nvim/os/os_defs.h index 5e164b54a5..14c210c69c 100644 --- a/src/nvim/os/os_defs.h +++ b/src/nvim/os/os_defs.h @@ -16,7 +16,7 @@ #define BASENAMELEN (NAME_MAX - 5) // Use the system path length if it makes sense. -#if defined(PATH_MAX) && (PATH_MAX > 1000) +#if defined(PATH_MAX) && (PATH_MAX > 1024) # define MAXPATHL PATH_MAX #else # define MAXPATHL 1024 diff --git a/src/nvim/path.c b/src/nvim/path.c index 3d1def8dd4..cdb16dbef1 100644 --- a/src/nvim/path.c +++ b/src/nvim/path.c @@ -398,8 +398,12 @@ char *concat_fnames_realloc(char *fname1, const char *fname2, bool sep) void add_pathsep(char *p) FUNC_ATTR_NONNULL_ALL { - if (*p != NUL && !after_pathsep(p, p + strlen(p))) - strcat(p, PATHSEPSTR); + const size_t len = strlen(p); + const size_t pathsep_len = sizeof(PATHSEPSTR); + assert(len < MAXPATHL - pathsep_len); + if (*p != NUL && !after_pathsep(p, p + len)) { + memcpy(p + len, PATHSEPSTR, pathsep_len); + } } /// Get an allocated copy of the full path to a file. diff --git a/src/nvim/vim.h b/src/nvim/vim.h index 8271abda8d..458d23fcad 100644 --- a/src/nvim/vim.h +++ b/src/nvim/vim.h @@ -269,6 +269,7 @@ enum { #define STRCAT(d, s) strcat((char *)(d), (char *)(s)) #define STRNCAT(d, s, n) strncat((char *)(d), (char *)(s), (size_t)(n)) +#define STRLCAT(d, s, n) xstrlcat((char *)(d), (char *)(s), (size_t)(n)) # define vim_strpbrk(s, cs) (char_u *)strpbrk((char *)(s), (char *)(cs)) |