aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/eval/userfunc.c
diff options
context:
space:
mode:
authorAndreas Schneider <asn@cryptomilk.org>2023-04-21 11:07:56 +0200
committerAndreas Schneider <asn@cryptomilk.org>2023-04-21 12:14:48 +0200
commit9802de933484cc0a69ee328f3e4e6efbb83c308e (patch)
treef966ef38fafa0e18f55b7a573a18eb59fbd9616d /src/nvim/eval/userfunc.c
parent2819718873a38c68cca0295f59186444d8534e06 (diff)
downloadrneovim-9802de933484cc0a69ee328f3e4e6efbb83c308e.tar.gz
rneovim-9802de933484cc0a69ee328f3e4e6efbb83c308e.tar.bz2
rneovim-9802de933484cc0a69ee328f3e4e6efbb83c308e.zip
fix(userfunc): fix possible out of bound access
In file included from /usr/include/string.h:535, from gsrc/nvim/eval/userfunc.c:11: In function ‘strcpy’, inlined from ‘cat_func_name’ at gsrc/nvim/eval/userfunc.c:662:5, inlined from ‘get_user_func_name’ at gsrc/nvim/eval/userfunc.c:2854:5: /usr/include/bits/string_fortified.h:79:10: warning: ‘__builtin___strcpy_chk’ offset 0 from the object at ‘<unknown>’ is out of the bounds of referenced subobject ‘uf_name’ with ty pe ‘char[]’ at offset 0 [-Warray-bounds=] 79 | return __builtin___strcpy_chk (__dest, __src, __glibc_objsize (__dest)); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ In file included from gsrc/nvim/eval/typval.h:10, from gsrc/nvim/buffer_defs.h:20, from gsrc/nvim/autocmd.h:8, from gsrc/nvim/eval/userfunc.c:15: gsrc/nvim/eval/typval_defs.h: In function ‘get_user_func_name’: gsrc/nvim/eval/typval_defs.h:342:8: note: subobject ‘uf_name’ declared here 342 | char uf_name[]; ///< Name of function (actual size equals name); | ^~~~~~~
Diffstat (limited to 'src/nvim/eval/userfunc.c')
-rw-r--r--src/nvim/eval/userfunc.c18
1 files changed, 12 insertions, 6 deletions
diff --git a/src/nvim/eval/userfunc.c b/src/nvim/eval/userfunc.c
index 51e109fdfb..b71e6c9cff 100644
--- a/src/nvim/eval/userfunc.c
+++ b/src/nvim/eval/userfunc.c
@@ -653,14 +653,20 @@ ufunc_T *find_func(const char *name)
/// Copy the function name of "fp" to buffer "buf".
/// "buf" must be able to hold the function name plus three bytes.
/// Takes care of script-local function names.
-static void cat_func_name(char *buf, ufunc_T *fp)
+static void cat_func_name(char *buf, size_t buflen, ufunc_T *fp)
{
- if ((uint8_t)fp->uf_name[0] == K_SPECIAL) {
- STRCPY(buf, "<SNR>");
- STRCAT(buf, fp->uf_name + 3);
+ int len = -1;
+ size_t uflen = strlen(fp->uf_name);
+ assert(uflen > 0);
+
+ if ((uint8_t)fp->uf_name[0] == K_SPECIAL && uflen > 3) {
+ len = snprintf(buf, buflen, "<SNR>%s", fp->uf_name + 3);
} else {
- STRCPY(buf, fp->uf_name);
+ len = snprintf(buf, buflen, "%s", fp->uf_name);
}
+
+ (void)len; // Avoid unused warning on release builds
+ assert(len > 0);
}
/// Add a number variable "name" to dict "dp" with value "nr".
@@ -2851,7 +2857,7 @@ char *get_user_func_name(expand_T *xp, int idx)
return fp->uf_name; // Prevent overflow.
}
- cat_func_name(IObuff, fp);
+ cat_func_name(IObuff, IOSIZE, fp);
if (xp->xp_context != EXPAND_USER_FUNC) {
STRCAT(IObuff, "(");
if (!fp->uf_varargs && GA_EMPTY(&fp->uf_args)) {