mirror of
https://github.com/neovim/neovim.git
synced 2024-12-24 13:15:09 -07:00
vim-patch:8.2.3362: buffer overflow when completing long tag name (#15449)
Problem: Buffer overflow when completing long tag name.
Solution: Allocate the buffer dynamically. (Gregory Anders, closes vim/vim#8769)
489d60996d
This commit is contained in:
parent
10d7d73b2d
commit
8d62f5fd58
@ -3061,24 +3061,26 @@ expand_tags (
|
|||||||
)
|
)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
int c;
|
int extra_flag;
|
||||||
int tagnmflag;
|
char_u *name_buf;
|
||||||
char_u tagnm[100];
|
size_t name_buf_size = 100;
|
||||||
tagptrs_T t_p;
|
tagptrs_T t_p;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (tagnames)
|
name_buf = xmalloc(name_buf_size);
|
||||||
tagnmflag = TAG_NAMES;
|
|
||||||
else
|
if (tagnames) {
|
||||||
tagnmflag = 0;
|
extra_flag = TAG_NAMES;
|
||||||
|
} else {
|
||||||
|
extra_flag = 0;
|
||||||
|
}
|
||||||
if (pat[0] == '/') {
|
if (pat[0] == '/') {
|
||||||
ret = find_tags(pat + 1, num_file, file,
|
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);
|
TAG_MANY, curbuf->b_ffname);
|
||||||
} else {
|
} else {
|
||||||
ret = find_tags(pat, num_file, file,
|
ret = find_tags(pat, num_file, file,
|
||||||
TAG_REGEXP | tagnmflag | TAG_VERBOSE
|
TAG_REGEXP | extra_flag | TAG_VERBOSE | TAG_NO_TAGFUNC | TAG_NOIC,
|
||||||
| TAG_NO_TAGFUNC | TAG_NOIC,
|
|
||||||
TAG_MANY, curbuf->b_ffname);
|
TAG_MANY, curbuf->b_ffname);
|
||||||
}
|
}
|
||||||
if (ret == OK && !tagnames) {
|
if (ret == OK && !tagnames) {
|
||||||
@ -3086,18 +3088,29 @@ expand_tags (
|
|||||||
* "<tagname>\0<kind>\0<filename>\0"
|
* "<tagname>\0<kind>\0<filename>\0"
|
||||||
*/
|
*/
|
||||||
for (i = 0; i < *num_file; i++) {
|
for (i = 0; i < *num_file; i++) {
|
||||||
|
size_t len;
|
||||||
|
|
||||||
parse_match((*file)[i], &t_p);
|
parse_match((*file)[i], &t_p);
|
||||||
c = (int)(t_p.tagname_end - t_p.tagname);
|
len = t_p.tagname_end - t_p.tagname;
|
||||||
memmove(tagnm, t_p.tagname, (size_t)c);
|
if (len > name_buf_size - 3) {
|
||||||
tagnm[c++] = 0;
|
char_u *buf;
|
||||||
tagnm[c++] = (t_p.tagkind != NULL && *t_p.tagkind)
|
|
||||||
? *t_p.tagkind : 'f';
|
name_buf_size = len + 3;
|
||||||
tagnm[c++] = 0;
|
buf = xrealloc(name_buf, name_buf_size);
|
||||||
memmove((*file)[i] + c, t_p.fname, t_p.fname_end - t_p.fname);
|
name_buf = buf;
|
||||||
(*file)[i][c + (t_p.fname_end - t_p.fname)] = 0;
|
}
|
||||||
memmove((*file)[i], tagnm, (size_t)c);
|
|
||||||
|
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;
|
||||||
|
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;
|
||||||
|
memmove((*file)[i], name_buf, len);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
xfree(name_buf);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -548,6 +548,16 @@ func Test_tag_line_toolong()
|
|||||||
call assert_equal('Xsomewhere', expand('%'))
|
call assert_equal('Xsomewhere', expand('%'))
|
||||||
call assert_equal(3, getcurpos()[1])
|
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('Xtags')
|
||||||
call delete('Xsomewhere')
|
call delete('Xsomewhere')
|
||||||
set tags&
|
set tags&
|
||||||
|
Loading…
Reference in New Issue
Block a user