summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2021-12-28 17:23:12 +0000
committerBram Moolenaar <Bram@vim.org>2021-12-28 17:23:12 +0000
commit4bf1006cae7e87259ccd5219128c3dba75774441 (patch)
tree85c8aa460d2787cc71160a7a3e8fddaa57e84f36 /src
parent8bb3fe4d4dcd27c02e903f6772fdc8fe2e9eba70 (diff)
patch 8.2.3923: Vim9: double free with split argument list in nested functionv8.2.3923
Problem: Vim9: double free if a nested function has a line break in the argument list. Solution: Set cmdlinep when freeing the previous line.
Diffstat (limited to 'src')
-rw-r--r--src/testdir/test_vim9_func.vim20
-rw-r--r--src/userfunc.c2
-rw-r--r--src/version.c2
3 files changed, 23 insertions, 1 deletions
diff --git a/src/testdir/test_vim9_func.vim b/src/testdir/test_vim9_func.vim
index 1a14c10167..88c0af8e0d 100644
--- a/src/testdir/test_vim9_func.vim
+++ b/src/testdir/test_vim9_func.vim
@@ -1669,7 +1669,7 @@ def Test_error_in_nested_function()
assert_fails('FuncWithForwardCall()', 'E1096:', '', 1, 'FuncWithForwardCall')
enddef
-def Test_nested_functin_with_nextcmd()
+def Test_nested_function_with_nextcmd()
var lines =<< trim END
vim9script
# Define an outer function
@@ -1689,6 +1689,24 @@ def Test_nested_functin_with_nextcmd()
CheckScriptFailure(lines, 'E476: Invalid command: AAAAA')
enddef
+def Test_nested_function_with_args_split()
+ var lines =<< trim END
+ vim9script
+ def FirstFunction()
+ def SecondFunction(
+ )
+ # had a double free if the right parenthesis of the nested function is
+ # on the next line
+
+ enddef|BBBB
+ enddef
+ # Compile all functions
+ defcompile
+ END
+ # FIXME: this should fail on the BBBB
+ CheckScriptSuccess(lines)
+enddef
+
def Test_return_type_wrong()
CheckScriptFailure([
'def Func(): number',
diff --git a/src/userfunc.c b/src/userfunc.c
index e1028e7728..a7cbac3c86 100644
--- a/src/userfunc.c
+++ b/src/userfunc.c
@@ -219,6 +219,8 @@ get_function_args(
if (theline == NULL)
break;
vim_free(*line_to_free);
+ if (*eap->cmdlinep == *line_to_free)
+ *eap->cmdlinep = theline;
*line_to_free = theline;
whitep = (char_u *)" ";
p = skipwhite(theline);
diff --git a/src/version.c b/src/version.c
index 6c8bced722..5d22d98e8d 100644
--- a/src/version.c
+++ b/src/version.c
@@ -750,6 +750,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 3923,
+/**/
3922,
/**/
3921,