]> granicus.if.org Git - vim/commitdiff
patch 8.2.4309: Vim9: crash when using a partial in the wrong context v8.2.4309
authorBram Moolenaar <Bram@vim.org>
Sun, 6 Feb 2022 13:55:03 +0000 (13:55 +0000)
committerBram Moolenaar <Bram@vim.org>
Sun, 6 Feb 2022 13:55:03 +0000 (13:55 +0000)
Problem:    Vim9: crash when using a partial in the wrong context.
Solution:   Don't use an NULL outer pointer. (closes #9706)

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

index 55297cb652f40cb718aad043cf59553e41849b69..e781a21a145f37034c234254633afb7d1a1668a2 100644 (file)
@@ -3125,6 +3125,35 @@ def Test_partial_call()
   v9.CheckScriptFailure(lines, 'E1235:')
 enddef
 
+" Using "idx" from a legacy global function does not work.
+" This caused a crash when called from legacy context.
+func Test_partial_call_fails()
+  let lines =<< trim END
+      vim9script
+
+      var l = ['a', 'b', 'c']
+      def Iter(container: any): any
+        var idx = -1
+        var obj = {state: container}
+        def g:__NextItem__(self: dict<any>): any
+          ++idx
+          return self.state[idx]
+        enddef
+        obj.__next__ = function('g:__NextItem__', [obj])
+        return obj
+      enddef
+
+      var it = Iter(l)
+      echo it.__next__()
+  END
+  call writefile(lines, 'XpartialCall')
+  try
+    source XpartialCall
+  catch /E1248:/
+  endtry
+  call delete('XpartialCall')
+endfunc
+
 def Test_cmd_modifier()
   tab echo '0'
   v9.CheckDefFailure(['5tab echo 3'], 'E16:')
index 4c48d5f60c2bf62bec251fdfe25a9e2020516d35..37d653d3a5afaa19ae009badaffe75b4ca9f8567 100644 (file)
@@ -746,6 +746,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    4309,
 /**/
     4308,
 /**/
index cac8c519d904fee29fca15c588a31058bfa3fa16..6c79ff7df316b280f60e26e8ff02e49c15cfd6d7 100644 (file)
@@ -1694,7 +1694,7 @@ handle_debug(isn_T *iptr, ectx_T *ectx)
 }
 
 /*
- * Store a value in a list or dict variable.
+ * Store a value in a list, dict or blob variable.
  * Returns OK, FAIL or NOTDONE (uncatchable error).
  */
     static int
@@ -5081,12 +5081,16 @@ call_def_function(
                goto failed_early;
            if (partial != NULL)
            {
-               if (partial->pt_outer.out_stack == NULL && current_ectx != NULL)
+               if (partial->pt_outer.out_stack == NULL)
                {
-                   if (current_ectx->ec_outer_ref != NULL
-                           && current_ectx->ec_outer_ref->or_outer != NULL)
-                       ectx.ec_outer_ref->or_outer =
+                   if (current_ectx != NULL)
+                   {
+                       if (current_ectx->ec_outer_ref != NULL
+                              && current_ectx->ec_outer_ref->or_outer != NULL)
+                           ectx.ec_outer_ref->or_outer =
                                          current_ectx->ec_outer_ref->or_outer;
+                   }
+                   // Should there be an error here?
                }
                else
                {