]> granicus.if.org Git - vim/commitdiff
patch 8.2.5169: nested :source may use NULL pointer v8.2.5169
authorBram Moolenaar <Bram@vim.org>
Mon, 27 Jun 2022 19:15:10 +0000 (20:15 +0100)
committerBram Moolenaar <Bram@vim.org>
Mon, 27 Jun 2022 19:15:10 +0000 (20:15 +0100)
Problem:    Nested :source may use NULL pointer.
Solution:   Do not use the NULL pointer.

src/eval.c
src/testdir/test_vimscript.vim
src/version.c

index dce78f7f04190513630a8cdb53fbac0ba40d6523..42b883e9b00bd3e86af7d06d3c192781c84fe051 100644 (file)
@@ -2387,27 +2387,32 @@ eval0_retarg(
 
     p = skipwhite(arg);
     ret = eval1(&p, rettv, evalarg);
-    expr_end = p;
-    p = skipwhite(p);
 
-    // In Vim9 script a command block is not split at NL characters for
-    // commands using an expression argument.  Skip over a '#' comment to check
-    // for a following NL.  Require white space before the '#'.
-    if (in_vim9script() && p > expr_end && retarg == NULL)
-       while (*p == '#')
-       {
-           char_u *nl = vim_strchr(p, NL);
+    if (ret != FAIL)
+    {
+       expr_end = p;
+       p = skipwhite(p);
 
-           if (nl == NULL)
-               break;
-           p = skipwhite(nl + 1);
-           if (eap != NULL && *p != NUL)
-               eap->nextcmd = p;
-           check_for_end = FALSE;
-       }
+       // In Vim9 script a command block is not split at NL characters for
+       // commands using an expression argument.  Skip over a '#' comment to
+       // check for a following NL.  Require white space before the '#'.
+       if (in_vim9script() && p > expr_end && retarg == NULL)
+           while (*p == '#')
+           {
+               char_u *nl = vim_strchr(p, NL);
+
+               if (nl == NULL)
+                   break;
+               p = skipwhite(nl + 1);
+               if (eap != NULL && *p != NUL)
+                   eap->nextcmd = p;
+               check_for_end = FALSE;
+           }
+
+       if (check_for_end)
+           end_error = !ends_excmd2(arg, p);
+    }
 
-    if (ret != FAIL && check_for_end)
-       end_error = !ends_excmd2(arg, p);
     if (ret == FAIL || end_error)
     {
        if (ret != FAIL)
@@ -2433,7 +2438,8 @@ eval0_retarg(
        // Some of the expression may not have been consumed.  Do not check for
        // a next command to avoid more errors, unless "|" is following, which
        // could only be a command separator.
-       if (eap != NULL && skipwhite(p)[0] == '|' && skipwhite(p)[1] != '|')
+       if (eap != NULL && p != NULL
+                         &&  skipwhite(p)[0] == '|' && skipwhite(p)[1] != '|')
            eap->nextcmd = check_nextcmd(p);
        return FAIL;
     }
index c9f58c23976c7bb0176e48e0a330a0246623b4f8..07dc59d15a13b53b82c87a9ded381eb77518bcae 100644 (file)
@@ -7528,6 +7528,25 @@ func Test_for_over_string()
   call assert_equal('', res)
 endfunc
 
+" Test for deeply nested :source command  {{{1
+func Test_deeply_nested_source()
+  let lines =<< trim END
+
+      so
+      sil 0scr
+      delete
+      so
+      0
+  END
+  call writefile(["vim9 silent! @0 \n/"] + lines, 'Xnested.vim')
+
+  " this must not crash
+  let cmd = GetVimCommand() .. " -e -s -S Xnested.vim -c qa!"
+  call system(cmd)
+
+  call delete('Xnested.vim')
+endfunc
+
 "-------------------------------------------------------------------------------
 " Modelines                                                                {{{1
 " vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker
index 5ac1cb93d0a8a0dd20513aa9ce071f69b5c8b74e..4a7e83f9c450ef4cff52bed7e67c6b8aa2a95198 100644 (file)
@@ -735,6 +735,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    5169,
 /**/
     5168,
 /**/