Patch 8.2.2781
Problem:    Add() silently skips when adding to null list or blob.
Solution:   Give an error in Vim9 script.  Allocate blob when it is NULL like
            with list and dict.
Files:      src/list.c, src/evalvars.c, src/vim9execute.c,
            src/testdir/test_blob.vim, src/testdir/test_vim9_builtin.vim


*** ../vim-8.2.2780/src/list.c  2021-04-13 20:53:09.846201149 +0200
--- src/list.c  2021-04-18 13:43:47.451965061 +0200
***************
*** 2412,2433 ****
      void
  f_add(typval_T *argvars, typval_T *rettv)
  {
-     list_T    *l;
-     blob_T    *b;
- 
      rettv->vval.v_number = 1; // Default: Failed
      if (argvars[0].v_type == VAR_LIST)
      {
!       if ((l = argvars[0].vval.v_list) != NULL
!               && !value_check_lock(l->lv_lock,
!                                        (char_u *)N_("add() argument"), TRUE)
                && list_append_tv(l, &argvars[1]) == OK)
            copy_tv(&argvars[0], rettv);
      }
      else if (argvars[0].v_type == VAR_BLOB)
      {
!       if ((b = argvars[0].vval.v_blob) != NULL
!               && !value_check_lock(b->bv_lock,
                                         (char_u *)N_("add() argument"), TRUE))
        {
            int         error = FALSE;
--- 2412,2444 ----
      void
  f_add(typval_T *argvars, typval_T *rettv)
  {
      rettv->vval.v_number = 1; // Default: Failed
      if (argvars[0].v_type == VAR_LIST)
      {
!       list_T  *l = argvars[0].vval.v_list;
! 
!       if (l == NULL)
!       {
!           if (in_vim9script())
!               emsg(_(e_cannot_add_to_null_list));
!       }
!       else if (!value_check_lock(l->lv_lock,
!                                         (char_u *)N_("add() argument"), TRUE)
                && list_append_tv(l, &argvars[1]) == OK)
+       {
            copy_tv(&argvars[0], rettv);
+       }
      }
      else if (argvars[0].v_type == VAR_BLOB)
      {
!       blob_T  *b = argvars[0].vval.v_blob;
! 
!       if (b == NULL)
!       {
!           if (in_vim9script())
!               emsg(_(e_cannot_add_to_null_blob));
!       }
!       else if (!value_check_lock(b->bv_lock,
                                         (char_u *)N_("add() argument"), TRUE))
        {
            int         error = FALSE;
*** ../vim-8.2.2780/src/evalvars.c      2021-04-14 13:30:42.974156744 +0200
--- src/evalvars.c      2021-04-18 14:01:02.577209532 +0200
***************
*** 2662,2667 ****
--- 2662,2673 ----
                if (tv->vval.v_list != NULL)
                    ++tv->vval.v_list->lv_refcount;
            }
+           else if (tv->v_type == VAR_BLOB && tv->vval.v_blob == NULL)
+           {
+               tv->vval.v_blob = blob_alloc();
+               if (tv->vval.v_blob != NULL)
+                   ++tv->vval.v_blob->bv_refcount;
+           }
            copy_tv(tv, rettv);
        }
      }
*** ../vim-8.2.2780/src/vim9execute.c   2021-04-18 13:15:54.524840780 +0200
--- src/vim9execute.c   2021-04-18 14:08:41.796295223 +0200
***************
*** 1020,1025 ****
--- 1020,1029 ----
            if (tv->vval.v_dict == NULL)
                (void)rettv_dict_alloc(tv);
            break;
+       case VAR_BLOB:
+           if (tv->vval.v_blob == NULL)
+               (void)rettv_blob_alloc(tv);
+           break;
        default:
            break;
      }
*** ../vim-8.2.2780/src/testdir/test_blob.vim   2021-04-18 13:15:54.524840780 
+0200
--- src/testdir/test_blob.vim   2021-04-18 13:47:51.655092168 +0200
***************
*** 316,342 ****
  endfunc
  
  func Test_blob_concatenate()
!   let b = 0z0011
!   let b += 0z2233
!   call assert_equal(0z00112233, b)
! 
!   call assert_fails('let b += "a"')
!   call assert_fails('let b += 88')
! 
!   let b = 0zDEAD + 0zBEEF
!   call assert_equal(0zDEADBEEF, b)
  endfunc
  
  func Test_blob_add()
    let b = 0z0011
-   call add(b, 0x22)
-   call assert_equal(0z001122, b)
    call add(b, '51')
!   call assert_equal(0z00112233, b)
    call assert_equal(1, add(test_null_blob(), 0x22))
  
!   call assert_fails('call add(b, [9])', 'E745:')
!   call assert_fails('call add("", 0x01)', 'E897:')
  endfunc
  
  func Test_blob_empty()
--- 316,374 ----
  endfunc
  
  func Test_blob_concatenate()
!   let lines =<< trim END
!       VAR b = 0z0011
!       LET b += 0z2233
!       call assert_equal(0z00112233, b)
! 
!       LET b = 0zDEAD + 0zBEEF
!       call assert_equal(0zDEADBEEF, b)
!   END
!   call CheckLegacyAndVim9Success(lines)
! 
!   let lines =<< trim END
!       VAR b = 0z0011
!       LET b += "a"
!   END
!   call CheckLegacyAndVim9Failure(lines, ['E734:', 'E1012:', 'E734:'])
! 
!   let lines =<< trim END
!       VAR b = 0z0011
!       LET b += 88
!   END
!   call CheckLegacyAndVim9Failure(lines, ['E734:', 'E1012:', 'E734:'])
  endfunc
  
  func Test_blob_add()
+   let lines =<< trim END
+       VAR b = 0z0011
+       call add(b, 0x22)
+       call assert_equal(0z001122, b)
+   END
+   call CheckLegacyAndVim9Success(lines)
+ 
+   " Only works in legacy script
    let b = 0z0011
    call add(b, '51')
!   call assert_equal(0z001133, b)
    call assert_equal(1, add(test_null_blob(), 0x22))
  
!   let lines =<< trim END
!       VAR b = 0z0011
!       call add(b, [9])
!   END
!   call CheckLegacyAndVim9Failure(lines, ['E745:', 'E1012:', 'E745:'])
! 
!   let lines =<< trim END
!       VAR b = 0z0011
!       call add("", 0x01)
!   END
!   call CheckLegacyAndVim9Failure(lines, 'E897:')
! 
!   let lines =<< trim END
!       add(test_null_blob(), 0x22)
!   END
!   call CheckDefExecAndScriptFailure(lines, 'E1131:')
  endfunc
  
  func Test_blob_empty()
*** ../vim-8.2.2780/src/testdir/test_vim9_builtin.vim   2021-04-10 
20:10:14.644409608 +0200
--- src/testdir/test_vim9_builtin.vim   2021-04-18 14:10:57.895942582 +0200
***************
*** 87,96 ****
--- 87,109 ----
    CheckDefFailure(lines, 'E1012:', 2)
  
    lines =<< trim END
+       add(test_null_list(), 123)
+   END
+   CheckDefExecAndScriptFailure(lines, 'E1130:', 1)
+ 
+   lines =<< trim END
        var l: list<number> = test_null_list()
        add(l, 123)
    END
    CheckDefExecFailure(lines, 'E1130:', 2)
+ 
+   # Getting variable with NULL list allocates a new list at script level
+   lines =<< trim END
+       vim9script
+       var l: list<number> = test_null_list()
+       add(l, 123)
+   END
+   CheckScriptSuccess(lines)
  enddef
  
  def Test_add_blob()
***************
*** 109,118 ****
--- 122,144 ----
    CheckDefFailure(lines, 'E1012:', 2)
  
    lines =<< trim END
+       add(test_null_blob(), 123)
+   END
+   CheckDefExecAndScriptFailure(lines, 'E1131:', 1)
+ 
+   lines =<< trim END
        var b: blob = test_null_blob()
        add(b, 123)
    END
    CheckDefExecFailure(lines, 'E1131:', 2)
+ 
+   # Getting variable with NULL blob allocates a new blob at script level
+   lines =<< trim END
+       vim9script
+       var b: blob = test_null_blob()
+       add(b, 123)
+   END
+   CheckScriptSuccess(lines)
  enddef
  
  def Test_append()
*** ../vim-8.2.2780/src/version.c       2021-04-18 13:15:54.528840765 +0200
--- src/version.c       2021-04-18 14:01:57.421131734 +0200
***************
*** 752,753 ****
--- 752,755 ----
  {   /* Add new patch number below this line */
+ /**/
+     2781,
  /**/

-- 
Support your right to bare arms!  Wear short sleeves!

 /// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net   \\\
///                                                                      \\\
\\\        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ ///
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/vim_dev/202104181213.13ICDLfr305525%40masaka.moolenaar.net.

Raspunde prin e-mail lui