]> granicus.if.org Git - vim/commitdiff
patch 8.2.2810: Vim9: crash when calling a function in a substitute expression v8.2.2810
authorBram Moolenaar <Bram@vim.org>
Sun, 25 Apr 2021 12:48:49 +0000 (14:48 +0200)
committerBram Moolenaar <Bram@vim.org>
Sun, 25 Apr 2021 12:48:49 +0000 (14:48 +0200)
Problem:    Vim9: crash when calling a function in a substitute expression.
Solution:   Set the instructions back to the substitute expression
            instrunctions. (closes #8148)

src/testdir/test_vim9_cmd.vim
src/version.c
src/vim9execute.c

index ab2ad6788ad1c5a2f3eefe96402d759c6d2a1700..401cc0f4cc747e36757927bd255f35c5e67ce269 100644 (file)
@@ -1194,10 +1194,31 @@ def Test_substitute_expr()
   endfor
   assert_equal('yes no abc', getline(1))
 
+  bwipe!
+
   CheckDefFailure(['s/from/\="x")/'], 'E488:')
   CheckDefFailure(['s/from/\="x"/9'], 'E488:')
 
-  bwipe!
+  # When calling a function the right instruction list needs to be restored.
+  var lines =<< trim END
+      vim9script
+      def Foo()
+          Bar([])
+      enddef
+      def Bar(l: list<number>)
+          s/^/\=Rep()/
+          for n in l[:]
+          endfor
+      enddef
+      def Rep(): string
+          return 'rep'
+      enddef
+      new
+      Foo()
+      assert_equal('rep', getline(1))
+      bwipe!
+  END
+  CheckScriptSuccess(lines)
 enddef
 
 def Test_redir_to_var()
index d235e94ebbeab9ad69f86eca0663739fdc86400f..53735b27ff306a301caf99151238efee58cadea4 100644 (file)
@@ -750,6 +750,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    2810,
 /**/
     2809,
 /**/
index c90fb65b679fba689800f2b2a8232d27a3715eb2..7f6ce5f33ae576a7d1c51d218c38a2457d30ee11 100644 (file)
@@ -601,6 +601,12 @@ func_return(ectx_T *ectx)
                                       + STACK_FRAME_IDX_OFF)->vval.v_number;
     ectx->ec_instr = INSTRUCTIONS(prev_dfunc);
 
+    // If the call was inside an ISN_SUBSTITUTE instruction need to use its
+    // list of instructions.
+    if (ectx->ec_instr[ectx->ec_iidx - 1].isn_type == ISN_SUBSTITUTE)
+       ectx->ec_instr = ectx->ec_instr[ectx->ec_iidx - 1]
+                                                     .isn_arg.subs.subs_instr;
+
     if (floc == NULL)
        ectx->ec_funclocal.floc_restore_cmdmod = FALSE;
     else