diff options
author | oni-link <knil.ino@gmail.com> | 2016-01-21 16:22:34 +0100 |
---|---|---|
committer | oni-link <knil.ino@gmail.com> | 2016-01-21 16:37:58 +0100 |
commit | a649299e76cb1a30cb3388a4bf1fe0410022374d (patch) | |
tree | 900e2b17833546326c7f1503e1f26153a3f9225c /src | |
parent | f2558890f54722ab31b1e073e9ce844750cd200a (diff) | |
download | rneovim-a649299e76cb1a30cb3388a4bf1fe0410022374d.tar.gz rneovim-a649299e76cb1a30cb3388a4bf1fe0410022374d.tar.bz2 rneovim-a649299e76cb1a30cb3388a4bf1fe0410022374d.zip |
coverity/133892: Resource leak
Variable tbuf going out of scope leaks the storage it points to.
We don't have to use the copy tbuf of a match. Because matches are always in
ctags style, we can operate on them directly.
Diffstat (limited to 'src')
-rw-r--r-- | src/nvim/if_cscope.c | 34 |
1 files changed, 16 insertions, 18 deletions
diff --git a/src/nvim/if_cscope.c b/src/nvim/if_cscope.c index 476dcc9478..347f214206 100644 --- a/src/nvim/if_cscope.c +++ b/src/nvim/if_cscope.c @@ -1646,7 +1646,6 @@ static char *cs_pathcomponents(char *path) static void cs_print_tags_priv(char **matches, char **cntxts, size_t num_matches) FUNC_ATTR_NONNULL_ALL { - char *fname, *lno, *extra, *tbuf; size_t num; char *globalcntx = "GLOBAL"; char *context; @@ -1681,26 +1680,23 @@ static void cs_print_tags_priv(char **matches, char **cntxts, assert(strcnt(matches[i], '\t') >= 2); size_t idx = i; - /* if we really wanted to, we could avoid this malloc and strcpy - * by parsing matches[i] on the fly and placing stuff into buf - * directly, but that's too much of a hassle - */ - tbuf = xmalloc(strlen(matches[idx]) + 1); - (void)strcpy(tbuf, matches[idx]); - - if (strtok(tbuf, (const char *)"\t") == NULL) - continue; - if ((fname = strtok(NULL, (const char *)"\t")) == NULL) - continue; - if ((lno = strtok(NULL, (const char *)"\t")) == NULL) - continue; - extra = strtok(NULL, (const char *)"\t"); + // Parse filename, line number and optional part. + char *fname = strchr(matches[i], '\t') + 1; + char *fname_end = strchr(fname, '\t'); + // Replace second '\t' in matches[i] with NUL to terminate fname. + *fname_end = NUL; - lno[strlen(lno)-2] = '\0'; /* ignore ;" at the end */ + char *lno = fname_end + 1; + char *extra = xstrchrnul(lno, '\t'); + // Ignore ;" at the end of lno. + char *lno_end = extra - 2; + *lno_end = NUL; + // Do we have an optional part? + extra = *extra ? extra + 1 : NULL; const char *csfmt_str = "%4zu %6s "; /* hopefully 'num' (num of matches) will be less than 10^16 */ - newsize = strlen(csfmt_str) + 16 + strlen(lno); + newsize = strlen(csfmt_str) + 16 + (size_t)(lno_end - lno); if (bufsize < newsize) { buf = xrealloc(buf, newsize); bufsize = newsize; @@ -1737,7 +1733,9 @@ static void cs_print_tags_priv(char **matches, char **cntxts, MSG_PUTS_LONG(extra); } - xfree(tbuf); /* only after printing extra due to strtok use */ + // restore matches[i] + *fname_end = '\t'; + *lno_end = ';'; if (msg_col) msg_putchar('\n'); |