aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/nvim/ex_cmds.c21
-rw-r--r--src/nvim/file_search.c3
-rw-r--r--src/nvim/globals.h1
-rw-r--r--src/nvim/memory.c27
-rw-r--r--src/nvim/os/os_defs.h2
-rw-r--r--src/nvim/path.c8
-rw-r--r--src/nvim/vim.h1
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))