Skip to content

Commit b7c21af

Browse files
committed
patch 8.2.2781: add() silently skips when adding to null list or blob
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.
1 parent d551d6c commit b7c21af

6 files changed

Lines changed: 101 additions & 20 deletions

File tree

src/evalvars.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2662,6 +2662,12 @@ eval_variable(
26622662
if (tv->vval.v_list != NULL)
26632663
++tv->vval.v_list->lv_refcount;
26642664
}
2665+
else if (tv->v_type == VAR_BLOB && tv->vval.v_blob == NULL)
2666+
{
2667+
tv->vval.v_blob = blob_alloc();
2668+
if (tv->vval.v_blob != NULL)
2669+
++tv->vval.v_blob->bv_refcount;
2670+
}
26652671
copy_tv(tv, rettv);
26662672
}
26672673
}

src/list.c

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2412,22 +2412,33 @@ f_mapnew(typval_T *argvars, typval_T *rettv)
24122412
void
24132413
f_add(typval_T *argvars, typval_T *rettv)
24142414
{
2415-
list_T *l;
2416-
blob_T *b;
2417-
24182415
rettv->vval.v_number = 1; // Default: Failed
24192416
if (argvars[0].v_type == VAR_LIST)
24202417
{
2421-
if ((l = argvars[0].vval.v_list) != NULL
2422-
&& !value_check_lock(l->lv_lock,
2423-
(char_u *)N_("add() argument"), TRUE)
2418+
list_T *l = argvars[0].vval.v_list;
2419+
2420+
if (l == NULL)
2421+
{
2422+
if (in_vim9script())
2423+
emsg(_(e_cannot_add_to_null_list));
2424+
}
2425+
else if (!value_check_lock(l->lv_lock,
2426+
(char_u *)N_("add() argument"), TRUE)
24242427
&& list_append_tv(l, &argvars[1]) == OK)
2428+
{
24252429
copy_tv(&argvars[0], rettv);
2430+
}
24262431
}
24272432
else if (argvars[0].v_type == VAR_BLOB)
24282433
{
2429-
if ((b = argvars[0].vval.v_blob) != NULL
2430-
&& !value_check_lock(b->bv_lock,
2434+
blob_T *b = argvars[0].vval.v_blob;
2435+
2436+
if (b == NULL)
2437+
{
2438+
if (in_vim9script())
2439+
emsg(_(e_cannot_add_to_null_blob));
2440+
}
2441+
else if (!value_check_lock(b->bv_lock,
24312442
(char_u *)N_("add() argument"), TRUE))
24322443
{
24332444
int error = FALSE;

src/testdir/test_blob.vim

Lines changed: 44 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -316,27 +316,59 @@ func Test_blob_for_loop()
316316
endfunc
317317

318318
func Test_blob_concatenate()
319-
let b = 0z0011
320-
let b += 0z2233
321-
call assert_equal(0z00112233, b)
319+
let lines =<< trim END
320+
VAR b = 0z0011
321+
LET b += 0z2233
322+
call assert_equal(0z00112233, b)
323+
324+
LET b = 0zDEAD + 0zBEEF
325+
call assert_equal(0zDEADBEEF, b)
326+
END
327+
call CheckLegacyAndVim9Success(lines)
322328

323-
call assert_fails('let b += "a"')
324-
call assert_fails('let b += 88')
329+
let lines =<< trim END
330+
VAR b = 0z0011
331+
LET b += "a"
332+
END
333+
call CheckLegacyAndVim9Failure(lines, ['E734:', 'E1012:', 'E734:'])
325334

326-
let b = 0zDEAD + 0zBEEF
327-
call assert_equal(0zDEADBEEF, b)
335+
let lines =<< trim END
336+
VAR b = 0z0011
337+
LET b += 88
338+
END
339+
call CheckLegacyAndVim9Failure(lines, ['E734:', 'E1012:', 'E734:'])
328340
endfunc
329341

330342
func Test_blob_add()
343+
let lines =<< trim END
344+
VAR b = 0z0011
345+
call add(b, 0x22)
346+
call assert_equal(0z001122, b)
347+
END
348+
call CheckLegacyAndVim9Success(lines)
349+
350+
" Only works in legacy script
331351
let b = 0z0011
332-
call add(b, 0x22)
333-
call assert_equal(0z001122, b)
334352
call add(b, '51')
335-
call assert_equal(0z00112233, b)
353+
call assert_equal(0z001133, b)
336354
call assert_equal(1, add(test_null_blob(), 0x22))
337355

338-
call assert_fails('call add(b, [9])', 'E745:')
339-
call assert_fails('call add("", 0x01)', 'E897:')
356+
let lines =<< trim END
357+
VAR b = 0z0011
358+
call add(b, [9])
359+
END
360+
call CheckLegacyAndVim9Failure(lines, ['E745:', 'E1012:', 'E745:'])
361+
362+
let lines =<< trim END
363+
VAR b = 0z0011
364+
call add("", 0x01)
365+
END
366+
call CheckLegacyAndVim9Failure(lines, 'E897:')
367+
368+
let lines =<< trim END
369+
add(test_null_blob(), 0x22)
370+
END
371+
call CheckDefExecAndScriptFailure(lines, 'E1131:')
340372
endfunc
341373

342374
func Test_blob_empty()

src/testdir/test_vim9_builtin.vim

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,11 +86,24 @@ def Test_add_list()
8686
END
8787
CheckDefFailure(lines, 'E1012:', 2)
8888

89+
lines =<< trim END
90+
add(test_null_list(), 123)
91+
END
92+
CheckDefExecAndScriptFailure(lines, 'E1130:', 1)
93+
8994
lines =<< trim END
9095
var l: list<number> = test_null_list()
9196
add(l, 123)
9297
END
9398
CheckDefExecFailure(lines, 'E1130:', 2)
99+
100+
# Getting variable with NULL list allocates a new list at script level
101+
lines =<< trim END
102+
vim9script
103+
var l: list<number> = test_null_list()
104+
add(l, 123)
105+
END
106+
CheckScriptSuccess(lines)
94107
enddef
95108

96109
def Test_add_blob()
@@ -108,11 +121,24 @@ def Test_add_blob()
108121
END
109122
CheckDefFailure(lines, 'E1012:', 2)
110123

124+
lines =<< trim END
125+
add(test_null_blob(), 123)
126+
END
127+
CheckDefExecAndScriptFailure(lines, 'E1131:', 1)
128+
111129
lines =<< trim END
112130
var b: blob = test_null_blob()
113131
add(b, 123)
114132
END
115133
CheckDefExecFailure(lines, 'E1131:', 2)
134+
135+
# Getting variable with NULL blob allocates a new blob at script level
136+
lines =<< trim END
137+
vim9script
138+
var b: blob = test_null_blob()
139+
add(b, 123)
140+
END
141+
CheckScriptSuccess(lines)
116142
enddef
117143

118144
def Test_append()

src/version.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -750,6 +750,8 @@ static char *(features[]) =
750750

751751
static int included_patches[] =
752752
{ /* Add new patch number below this line */
753+
/**/
754+
2781,
753755
/**/
754756
2780,
755757
/**/

src/vim9execute.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1020,6 +1020,10 @@ allocate_if_null(typval_T *tv)
10201020
if (tv->vval.v_dict == NULL)
10211021
(void)rettv_dict_alloc(tv);
10221022
break;
1023+
case VAR_BLOB:
1024+
if (tv->vval.v_blob == NULL)
1025+
(void)rettv_blob_alloc(tv);
1026+
break;
10231027
default:
10241028
break;
10251029
}

0 commit comments

Comments
 (0)