mirror of
https://github.com/vim/vim.git
synced 2025-09-23 03:43:49 -04:00
patch 8.2.3362: buffer overflow when completing long tag name
Problem: Buffer overflow when completing long tag name. Solution: Allocate the buffer dynamically. (Gregory Anders, closes #8769)
This commit is contained in:
committed by
Bram Moolenaar
parent
d895b1d918
commit
489d60996d
55
src/tag.c
55
src/tag.c
@@ -3878,23 +3878,27 @@ expand_tags(
|
||||
char_u ***file)
|
||||
{
|
||||
int i;
|
||||
int c;
|
||||
int tagnmflag;
|
||||
char_u tagnm[100];
|
||||
int extra_flag;
|
||||
char_u *name_buf;
|
||||
size_t name_buf_size = 100;
|
||||
tagptrs_T t_p;
|
||||
int ret;
|
||||
|
||||
name_buf = alloc(name_buf_size);
|
||||
if (name_buf == NULL)
|
||||
return FAIL;
|
||||
|
||||
if (tagnames)
|
||||
tagnmflag = TAG_NAMES;
|
||||
extra_flag = TAG_NAMES;
|
||||
else
|
||||
tagnmflag = 0;
|
||||
extra_flag = 0;
|
||||
if (pat[0] == '/')
|
||||
ret = find_tags(pat + 1, num_file, file,
|
||||
TAG_REGEXP | tagnmflag | TAG_VERBOSE | TAG_NO_TAGFUNC,
|
||||
TAG_REGEXP | extra_flag | TAG_VERBOSE | TAG_NO_TAGFUNC,
|
||||
TAG_MANY, curbuf->b_ffname);
|
||||
else
|
||||
ret = find_tags(pat, num_file, file,
|
||||
TAG_REGEXP | tagnmflag | TAG_VERBOSE | TAG_NO_TAGFUNC | TAG_NOIC,
|
||||
TAG_REGEXP | extra_flag | TAG_VERBOSE | TAG_NO_TAGFUNC | TAG_NOIC,
|
||||
TAG_MANY, curbuf->b_ffname);
|
||||
if (ret == OK && !tagnames)
|
||||
{
|
||||
@@ -3902,18 +3906,37 @@ expand_tags(
|
||||
// "<tagname>\0<kind>\0<filename>\0"
|
||||
for (i = 0; i < *num_file; i++)
|
||||
{
|
||||
size_t len;
|
||||
|
||||
parse_match((*file)[i], &t_p);
|
||||
c = (int)(t_p.tagname_end - t_p.tagname);
|
||||
mch_memmove(tagnm, t_p.tagname, (size_t)c);
|
||||
tagnm[c++] = 0;
|
||||
tagnm[c++] = (t_p.tagkind != NULL && *t_p.tagkind)
|
||||
? *t_p.tagkind : 'f';
|
||||
tagnm[c++] = 0;
|
||||
mch_memmove((*file)[i] + c, t_p.fname, t_p.fname_end - t_p.fname);
|
||||
(*file)[i][c + (t_p.fname_end - t_p.fname)] = 0;
|
||||
mch_memmove((*file)[i], tagnm, (size_t)c);
|
||||
len = t_p.tagname_end - t_p.tagname;
|
||||
if (len > name_buf_size - 3)
|
||||
{
|
||||
char_u *buf;
|
||||
|
||||
name_buf_size = len + 3;
|
||||
buf = vim_realloc(name_buf, name_buf_size);
|
||||
if (buf == NULL)
|
||||
{
|
||||
vim_free(name_buf);
|
||||
return FAIL;
|
||||
}
|
||||
name_buf = buf;
|
||||
}
|
||||
|
||||
mch_memmove(name_buf, t_p.tagname, len);
|
||||
name_buf[len++] = 0;
|
||||
name_buf[len++] = (t_p.tagkind != NULL && *t_p.tagkind)
|
||||
? *t_p.tagkind : 'f';
|
||||
name_buf[len++] = 0;
|
||||
mch_memmove((*file)[i] + len, t_p.fname,
|
||||
t_p.fname_end - t_p.fname);
|
||||
(*file)[i][len + (t_p.fname_end - t_p.fname)] = 0;
|
||||
mch_memmove((*file)[i], name_buf, len);
|
||||
}
|
||||
}
|
||||
|
||||
vim_free(name_buf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user