]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
patch 9.2.0149: Vim9: segfault when unletting an imported variable v9.2.0149
authorChristian Brabandt <cb@256bit.org>
Fri, 13 Mar 2026 16:57:00 +0000 (16:57 +0000)
committerChristian Brabandt <cb@256bit.org>
Fri, 13 Mar 2026 16:57:00 +0000 (16:57 +0000)
Problem:  do_unlet_var() unconditionally calls dictitem_remove() in its
          final else branch, but for imported items lp->ll_dict is NULL,
          causing a segfault (Peter Kenny)
Solution: Add a NULL check and return E1260 instead.

Affects :unlet at vim9script level and inside legacy :function.
The :def case already worked (handled in vim9cmds.c).

fixes:  #19637
closes: #19657

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Yegappan Lakshmanan <yegappan@yahoo.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
src/evalvars.c
src/testdir/test_vim9_assign.vim
src/version.c

index 9f0cc08c80c3741550d22bbda95be8bb032e8a4e..778e7152c6117be60cbcb74c352e3cb199a097ee 100644 (file)
@@ -2150,9 +2150,14 @@ do_unlet_var(
     else if (lp->ll_list != NULL)
        // unlet a List item.
        listitem_remove(lp->ll_list, lp->ll_li);
-    else
+    else if (lp->ll_dict != NULL)
        // unlet a Dictionary item.
        dictitem_remove(lp->ll_dict, lp->ll_di, "unlet");
+    else
+    {
+       semsg(_(e_cannot_unlet_imported_item_str), lp->ll_name);
+       return FAIL;
+    }
 
     return ret;
 }
index b915b666d5dee91154431781885b7766e8e5cb80..5043fad23f7755250005bc3f87b8047546efeda2 100644 (file)
@@ -2869,6 +2869,26 @@ def Test_unlet()
   END
   v9.CheckScriptFailure(lines, 'E1260:', 1)
 
+  # unlet imported item at script level
+  lines =<< trim END
+    vim9script
+    import './XunletExport.vim' as exp
+    unlet exp.svar
+  END
+  v9.CheckScriptFailure(lines, 'E1260:', 3)
+
+  # unlet imported item in legacy function
+  lines =<< trim END
+    vim9script
+    import './XunletExport.vim' as exp
+    function F()
+      unlet exp.svar
+    endfunction
+    call F()
+  END
+  # error in line 1 of the F()
+  v9.CheckScriptFailure(lines, 'E1260:', 1)
+
   $ENVVAR = 'foobar'
   assert_equal('foobar', $ENVVAR)
   unlet $ENVVAR
index 063e0a2ed66952364413cac9c5575aae3c00b410..762553cd582ab5707691342520d56a4ed257fec2 100644 (file)
@@ -734,6 +734,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    149,
 /**/
     148,
 /**/