0
0
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:
Gregory Anders
2021-08-21 16:21:19 +02:00
committed by Bram Moolenaar
parent d895b1d918
commit 489d60996d
3 changed files with 51 additions and 16 deletions

View File

@@ -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)
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';
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);
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;
}

View File

@@ -606,6 +606,16 @@ func Test_tag_line_toolong()
call assert_equal('Xsomewhere', expand('%'))
call assert_equal(3, getcurpos()[1])
" expansion on command line works with long lines when &wildoptions contains
" 'tagfile'
set wildoptions=tagfile
call writefile([
\ 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa file /^pattern$/;" f'
\ ], 'Xtags')
call feedkeys(":tag \<Tab>", 'tx')
" Should not crash
call assert_true(v:true)
call delete('Xtags')
call delete('Xsomewhere')
set tags&

View File

@@ -755,6 +755,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
3362,
/**/
3361,
/**/