Patch 8.0.0667
Problem: Memory access error when command follows :endfunction. (Nikolai
Pavlov)
Solution: Make memory handling in :function straightforward. (closes #1793)
Files: src/userfunc.c, src/testdir/test_vimscript.vim
*** ../vim-8.0.0666/src/userfunc.c 2017-06-23 20:52:21.575128772 +0200
--- src/userfunc.c 2017-06-24 14:47:44.523671380 +0200
***************
*** 1780,1785 ****
--- 1780,1786 ----
ex_function(exarg_T *eap)
{
char_u *theline;
+ char_u *line_to_free = NULL;
int j;
int c;
int saved_did_emsg;
***************
*** 2093,2102 ****
line_arg = p + 1;
}
}
- else if (eap->getline == NULL)
- theline = getcmdline(':', 0L, indent);
else
! theline = eap->getline(':', eap->cookie, indent);
if (KeyTyped)
lines_left = Rows - 1;
if (theline == NULL)
--- 2094,2108 ----
line_arg = p + 1;
}
}
else
! {
! vim_free(line_to_free);
! if (eap->getline == NULL)
! theline = getcmdline(':', 0L, indent);
! else
! theline = eap->getline(':', eap->cookie, indent);
! line_to_free = theline;
! }
if (KeyTyped)
lines_left = Rows - 1;
if (theline == NULL)
***************
*** 2130,2147 ****
/* Check for "endfunction". */
if (checkforcmd(&p, "endfunction", 4) && nesting-- == 0)
{
if (*p == '|')
! /* Another command follows. */
! eap->nextcmd = vim_strsave(p + 1);
else if (line_arg != NULL && *skipwhite(line_arg) != NUL)
! /* Another command follows. */
! eap->nextcmd = line_arg;
else if (*p != NUL && *p != '"' && p_verbose > 0)
give_warning2(
(char_u *)_("W22: Text found after :endfunction: %s"),
p, TRUE);
! if (line_arg == NULL)
! vim_free(theline);
break;
}
--- 2136,2164 ----
/* Check for "endfunction". */
if (checkforcmd(&p, "endfunction", 4) && nesting-- == 0)
{
+ char_u *nextcmd = NULL;
+
if (*p == '|')
! nextcmd = p + 1;
else if (line_arg != NULL && *skipwhite(line_arg) != NUL)
! nextcmd = line_arg;
else if (*p != NUL && *p != '"' && p_verbose > 0)
give_warning2(
(char_u *)_("W22: Text found after :endfunction: %s"),
p, TRUE);
! if (nextcmd != NULL)
! {
! /* Another command follows. If the line came from "eap" we
! * can simply point into it, otherwise we need to change
! * "eap->cmdlinep". */
! eap->nextcmd = nextcmd;
! if (line_to_free != NULL)
! {
! vim_free(*eap->cmdlinep);
! *eap->cmdlinep = line_to_free;
! line_to_free = NULL;
! }
! }
break;
}
***************
*** 2212,2235 ****
/* Add the line to the function. */
if (ga_grow(&newlines, 1 + sourcing_lnum_off) == FAIL)
- {
- if (line_arg == NULL)
- vim_free(theline);
goto erret;
- }
/* Copy the line to newly allocated memory. get_one_sourceline()
* allocates 250 bytes per line, this saves 80% on average. The cost
* is an extra alloc/free. */
p = vim_strsave(theline);
! if (p != NULL)
! {
! if (line_arg == NULL)
! vim_free(theline);
! theline = p;
! }
!
! ((char_u **)(newlines.ga_data))[newlines.ga_len++] = theline;
/* Add NULL lines for continuation lines, so that the line count is
* equal to the index in the growarray. */
--- 2229,2243 ----
/* Add the line to the function. */
if (ga_grow(&newlines, 1 + sourcing_lnum_off) == FAIL)
goto erret;
/* Copy the line to newly allocated memory. get_one_sourceline()
* allocates 250 bytes per line, this saves 80% on average. The cost
* is an extra alloc/free. */
p = vim_strsave(theline);
! if (p == NULL)
! goto erret;
! ((char_u **)(newlines.ga_data))[newlines.ga_len++] = p;
/* Add NULL lines for continuation lines, so that the line count is
* equal to the index in the growarray. */
***************
*** 2428,2433 ****
--- 2436,2442 ----
ga_clear_strings(&newlines);
ret_free:
vim_free(skip_until);
+ vim_free(line_to_free);
vim_free(fudi.fd_newkey);
vim_free(name);
did_emsg |= saved_did_emsg;
*** ../vim-8.0.0666/src/testdir/test_vimscript.vim 2017-06-23
20:52:21.575128772 +0200
--- src/testdir/test_vimscript.vim 2017-06-24 14:40:18.511173845 +0200
***************
*** 1379,1384 ****
--- 1379,1389 ----
delfunc Xtest
unlet done
+ " trailing line break
+ exe "func Xtest()\necho 'hello'\nendfunc\n"
+ call assert_true(exists('*Xtest'))
+ delfunc Xtest
+
set verbose=1
exe "func Xtest()\necho 'hello'\nendfunc \" garbage"
call assert_notmatch('W22:', split(execute('1messages'), "\n")[0])
***************
*** 1390,1395 ****
--- 1395,1405 ----
call assert_true(exists('*Xtest'))
delfunc Xtest
set verbose=0
+
+ function Foo()
+ echo 'hello'
+ endfunction | echo 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
+ delfunc Foo
endfunc
func Test_delfunction_force()
*** ../vim-8.0.0666/src/version.c 2017-06-23 23:00:03.933758799 +0200
--- src/version.c 2017-06-24 14:41:52.022439531 +0200
***************
*** 766,767 ****
--- 766,769 ----
{ /* Add new patch number below this line */
+ /**/
+ 667,
/**/
--
If bankers can count, how come they have eight windows and
only four tellers?
/// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net \\\
/// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\ an exciting new programming language -- http://www.Zimbu.org ///
\\\ help me help AIDS victims -- http://ICCF-Holland.org ///
--
--
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php
---
You received this message because you are subscribed to the Google Groups
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.