diff options
author | oni-link <knil.ino@gmail.com> | 2016-01-21 16:07:13 +0100 |
---|---|---|
committer | oni-link <knil.ino@gmail.com> | 2016-01-21 16:37:58 +0100 |
commit | 7a8e41e8ee56a1fcec07f85566022548d41a944a (patch) | |
tree | eb3111d27a36896eb38035e9f93f1d78a1f95302 /src | |
parent | bcbcf235f61bd75f965f35897784ea618fe7acb8 (diff) | |
download | rneovim-7a8e41e8ee56a1fcec07f85566022548d41a944a.tar.gz rneovim-7a8e41e8ee56a1fcec07f85566022548d41a944a.tar.bz2 rneovim-7a8e41e8ee56a1fcec07f85566022548d41a944a.zip |
coverity/13753: Dereference null return value
Dereferencing a pointer that might be null(ptag) when calling strlen().
False positive. A match always contains a tab, so ptag is never null.
Because matches are always in ctags style, we can rewrite the code to
not use strtok().
Diffstat (limited to 'src')
-rw-r--r-- | src/nvim/if_cscope.c | 37 |
1 files changed, 23 insertions, 14 deletions
diff --git a/src/nvim/if_cscope.c b/src/nvim/if_cscope.c index d236501b3f..af3a87211a 100644 --- a/src/nvim/if_cscope.c +++ b/src/nvim/if_cscope.c @@ -1632,35 +1632,43 @@ static char *cs_pathcomponents(char *path) return s; } -/* - * PRIVATE: cs_print_tags_priv - * - * called from cs_manage_matches() - */ +/// Print cscope output that was converted into ctags style entries. +/// +/// Only called from cs_manage_matches(). +/// +/// @param matches Array of cscope lines in ctags style. Every entry was +// produced with a format string of the form +// "%s\t%s\t%s;\"\t%s" or +// "%s\t%s\t%s;\"" +// by cs_make_vim_style_matches(). +/// @param cntxts Context for matches. +/// @param num_matches Number of entries in matches/cntxts, always greater 0. static void cs_print_tags_priv(char **matches, char **cntxts, - size_t num_matches) + size_t num_matches) FUNC_ATTR_NONNULL_ALL { - char *ptag; char *fname, *lno, *extra, *tbuf; size_t num; char *globalcntx = "GLOBAL"; char *context; char *cstag_msg = _("Cscope tag: %s"); - assert (num_matches > 0); - - tbuf = xmalloc(strlen(matches[0]) + 1); + assert(num_matches > 0); + assert(strcnt(matches[0], '\t') >= 2); - strcpy(tbuf, matches[0]); - ptag = strtok(tbuf, "\t"); + char *ptag = matches[0]; + char *ptag_end = strchr(ptag, '\t'); + assert(ptag_end >= ptag); + // NUL terminate tag string in matches[0]. + *ptag_end = NUL; - size_t newsize = strlen(cstag_msg) + strlen(ptag); + size_t newsize = strlen(cstag_msg) + (size_t)(ptag_end - ptag); char *buf = xmalloc(newsize); size_t bufsize = newsize; // Track available bufsize (void)sprintf(buf, cstag_msg, ptag); MSG_PUTS_ATTR(buf, hl_attr(HLF_T)); - xfree(tbuf); + // restore matches[0] + *ptag_end = '\t'; MSG_PUTS_ATTR(_("\n # line"), hl_attr(HLF_T)); /* strlen is 7 */ msg_advance(msg_col + 2); @@ -1668,6 +1676,7 @@ static void cs_print_tags_priv(char **matches, char **cntxts, num = 1; for (size_t i = 0; i < num_matches; i++) { + assert(strcnt(matches[i], '\t') >= 2); size_t idx = i; /* if we really wanted to, we could avoid this malloc and strcpy |