diff options
author | Jan Edmund Lazo <janedmundlazo@hotmail.com> | 2018-08-14 10:18:08 -0400 |
---|---|---|
committer | Jan Edmund Lazo <janedmundlazo@hotmail.com> | 2018-08-15 01:27:30 -0400 |
commit | 5e38ff105c20bc3920e840046f6af651c99f186c (patch) | |
tree | 02a7c86e013d0c73e7f01c1c8f96d6a5c5aef228 | |
parent | 84569693e109f322ed77948ce74c19af5f04b527 (diff) | |
download | rneovim-5e38ff105c20bc3920e840046f6af651c99f186c.tar.gz rneovim-5e38ff105c20bc3920e840046f6af651c99f186c.tar.bz2 rneovim-5e38ff105c20bc3920e840046f6af651c99f186c.zip |
vim-patch:8.0.1218: writing to freed memory in autocmd
Problem: Writing to freed memory in autocmd.
Solution: Make a copy of the tag line. (Dominique Pelle, closes vim/vim#2245)
https://github.com/vim/vim/commit/8d84ff1a3c8cfe59399d3f675ec080066582fdb6
-rw-r--r-- | src/nvim/tag.c | 32 | ||||
-rw-r--r-- | src/nvim/testdir/test_autocmd.vim | 18 |
2 files changed, 40 insertions, 10 deletions
diff --git a/src/nvim/tag.c b/src/nvim/tag.c index c09a13edb1..02dc36b57a 100644 --- a/src/nvim/tag.c +++ b/src/nvim/tag.c @@ -2217,6 +2217,16 @@ static bool test_for_static(tagptrs_T *tagp) return FALSE; } +// Returns the length of a matching tag line. +static size_t matching_line_len(const char_u *const lbuf) +{ + const char_u *p = lbuf + 1; + + // does the same thing as parse_match() + p += STRLEN(p) + 2; + return (p - lbuf) + STRLEN(p); +} + /* * Parse a line from a matching tag. Does not change the line itself. * @@ -2300,11 +2310,10 @@ static char_u *tag_full_fname(tagptrs_T *tagp) * * returns OK for success, NOTAGFILE when file not found, FAIL otherwise. */ -static int -jumpto_tag ( - char_u *lbuf, /* line from the tags file for this tag */ - int forceit, /* :ta with ! */ - int keep_help /* keep help flag (FALSE for cscope) */ +static int jumpto_tag( + const char_u *lbuf_arg, // line from the tags file for this tag + int forceit, // :ta with ! + int keep_help // keep help flag (FALSE for cscope) ) { int save_secure; @@ -2312,7 +2321,6 @@ jumpto_tag ( bool save_p_ws; int save_p_scs, save_p_ic; linenr_T save_lnum; - int csave = 0; char_u *str; char_u *pbuf; /* search pattern buffer */ char_u *pbuf_end; @@ -2327,6 +2335,9 @@ jumpto_tag ( char_u *full_fname = NULL; int old_KeyTyped = KeyTyped; /* getting the file may reset it */ const int l_g_do_tagpreview = g_do_tagpreview; + const size_t len = matching_line_len(lbuf_arg) + 1; + char_u *lbuf = xmalloc(len); + memmove(lbuf, lbuf_arg, len); pbuf = xmalloc(LSIZE); @@ -2336,8 +2347,7 @@ jumpto_tag ( goto erret; } - /* truncate the file name, so it can be used as a string */ - csave = *tagp.fname_end; + // truncate the file name, so it can be used as a string *tagp.fname_end = NUL; fname = tagp.fname; @@ -2447,7 +2457,10 @@ jumpto_tag ( else keep_help_flag = curbuf->b_help; } + if (getfile_result == GETFILE_UNUSED) { + // Careful: getfile() may trigger autocommands and call jumpto_tag() + // recursively. getfile_result = getfile(0, fname, NULL, true, (linenr_T)0, forceit); } keep_help_flag = false; @@ -2606,8 +2619,7 @@ jumpto_tag ( erret: g_do_tagpreview = 0; /* For next time */ - if (tagp.fname_end != NULL) - *tagp.fname_end = csave; + xfree(lbuf); xfree(pbuf); xfree(tofree_fname); xfree(full_fname); diff --git a/src/nvim/testdir/test_autocmd.vim b/src/nvim/testdir/test_autocmd.vim index e4ab3ccea8..10fea4dad3 100644 --- a/src/nvim/testdir/test_autocmd.vim +++ b/src/nvim/testdir/test_autocmd.vim @@ -248,6 +248,24 @@ func Test_augroup_warning() au! VimEnter endfunc +func Test_BufReadCmdHelp() + " This used to cause access to free memory + au BufReadCmd * e +h + help + + helpclose + au! BufReadCmd +endfunc + +func Test_BufReadCmdHelpJump() + " This used to cause access to free memory + au BufReadCmd * e +h{ + help + + helpclose + au! BufReadCmd +endfunc + func Test_augroup_deleted() " This caused a crash before E936 was introduced augroup x |