changeset 7498:3fcd3d235f7b v7.4.1051

commit https://github.com/vim/vim/commit/af8af8bfac5792fa64efbc524032d568cc7754f7 Author: Bram Moolenaar <Bram@vim.org> Date: Mon Jan 4 22:05:24 2016 +0100 patch 7.4.1051 Problem: Segfault when unletting "count". Solution: Check for readonly and locked first. (Dominique Pelle) Add a test.
author Christian Brabandt <cb@256bit.org>
date Mon, 04 Jan 2016 22:15:06 +0100
parents f176999cc60c
children 0f3b316a0db5
files src/eval.c src/testdir/test_alot.vim src/testdir/test_unlet.vim src/version.c
diffstat 4 files changed, 44 insertions(+), 12 deletions(-) [+]
line wrap: on
line diff
--- a/src/eval.c
+++ b/src/eval.c
@@ -3737,24 +3737,27 @@ do_unlet(name, forceit)
     ht = find_var_ht(name, &varname);
     if (ht != NULL && *varname != NUL)
     {
-	if (ht == &globvarht)
-	    d = &globvardict;
-	else if (current_funccal != NULL
-				 && ht == &current_funccal->l_vars.dv_hashtab)
-	    d = &current_funccal->l_vars;
-	else
-	{
-	    di = find_var_in_ht(ht, *name, (char_u *)"", FALSE);
-	    d = di->di_tv.vval.v_dict;
-	}
 	hi = hash_find(ht, varname);
 	if (!HASHITEM_EMPTY(hi))
 	{
 	    di = HI2DI(hi);
 	    if (var_check_fixed(di->di_flags, name, FALSE)
-		    || var_check_ro(di->di_flags, name, FALSE)
-		    || tv_check_lock(d->dv_lock, name, FALSE))
+		    || var_check_ro(di->di_flags, name, FALSE))
 		return FAIL;
+
+	    if (ht == &globvarht)
+		d = &globvardict;
+	    else if (current_funccal != NULL
+				 && ht == &current_funccal->l_vars.dv_hashtab)
+		d = &current_funccal->l_vars;
+	    else
+	    {
+		di = find_var_in_ht(ht, *name, (char_u *)"", FALSE);
+		d = di->di_tv.vval.v_dict;
+	    }
+	    if (d == NULL || tv_check_lock(d->dv_lock, name, FALSE))
+		return FAIL;
+
 	    delete_var(ht, hi);
 	    return OK;
 	}
--- a/src/testdir/test_alot.vim
+++ b/src/testdir/test_alot.vim
@@ -8,3 +8,4 @@ source test_searchpos.vim
 source test_set.vim
 source test_sort.vim
 source test_undolevels.vim
+source test_unlet.vim
new file mode 100644
--- /dev/null
+++ b/src/testdir/test_unlet.vim
@@ -0,0 +1,26 @@
+" Tests for :unlet
+
+func Test_read_only()
+  try
+    " this caused a crash
+    unlet count
+  catch
+    call assert_true(v:exception =~ ':E795:')
+  endtry
+endfunc
+
+func Test_existing()
+  let does_exist = 1
+  call assert_true(exists('does_exist'))
+  unlet does_exist
+  call assert_false(exists('does_exist'))
+endfunc
+
+func Test_not_existing()
+  unlet! does_not_exist
+  try
+    unlet does_not_exist
+  catch
+    call assert_true(v:exception =~ ':E108:')
+  endtry
+endfunc
--- a/src/version.c
+++ b/src/version.c
@@ -742,6 +742,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    1051,
+/**/
     1050,
 /**/
     1049,