Skip to content

Commit 348be7e

Browse files
committed
patch 8.2.1949: Vim9: using extend() on null dict is silently ignored
Problem: Vim9: using extend() on null dict is silently ignored. Solution: Give an error message. Initialize a dict variable with an empty dictionary. (closes #7251)
1 parent 4778b4d commit 348be7e

5 files changed

Lines changed: 82 additions & 7 deletions

File tree

src/errors.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -288,4 +288,8 @@ EXTERN char e_cannot_add_to_null_blob[]
288288
INIT(= N_("E1131: Cannot add to null blob"));
289289
EXTERN char e_missing_function_argument[]
290290
INIT(= N_("E1132: Missing function argument"));
291+
EXTERN char e_cannot_extend_null_dict[]
292+
INIT(= N_("E1133: Cannot extend a null dict"));
293+
EXTERN char e_cannot_extend_null_list[]
294+
INIT(= N_("E1134: Cannot extend a null list"));
291295
#endif

src/evalvars.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2553,7 +2553,22 @@ eval_variable(
25532553
ret = FAIL;
25542554
}
25552555
else if (rettv != NULL)
2556+
{
2557+
// If a list or dict variable wasn't initialized, do it now.
2558+
if (tv->v_type == VAR_DICT && tv->vval.v_dict == NULL)
2559+
{
2560+
tv->vval.v_dict = dict_alloc();
2561+
if (tv->vval.v_dict != NULL)
2562+
++tv->vval.v_dict->dv_refcount;
2563+
}
2564+
else if (tv->v_type == VAR_LIST && tv->vval.v_list == NULL)
2565+
{
2566+
tv->vval.v_list = list_alloc();
2567+
if (tv->vval.v_list != NULL)
2568+
++tv->vval.v_list->lv_refcount;
2569+
}
25562570
copy_tv(tv, rettv);
2571+
}
25572572
}
25582573

25592574
name[len] = cc;

src/list.c

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2303,9 +2303,13 @@ f_extend(typval_T *argvars, typval_T *rettv)
23032303
int error = FALSE;
23042304

23052305
l1 = argvars[0].vval.v_list;
2306+
if (l1 == NULL)
2307+
{
2308+
emsg(_(e_cannot_extend_null_list));
2309+
return;
2310+
}
23062311
l2 = argvars[1].vval.v_list;
2307-
if (l1 != NULL && !value_check_lock(l1->lv_lock, arg_errmsg, TRUE)
2308-
&& l2 != NULL)
2312+
if (!value_check_lock(l1->lv_lock, arg_errmsg, TRUE) && l2 != NULL)
23092313
{
23102314
if (argvars[2].v_type != VAR_UNKNOWN)
23112315
{
@@ -2339,9 +2343,13 @@ f_extend(typval_T *argvars, typval_T *rettv)
23392343
int i;
23402344

23412345
d1 = argvars[0].vval.v_dict;
2346+
if (d1 == NULL)
2347+
{
2348+
emsg(_(e_cannot_extend_null_dict));
2349+
return;
2350+
}
23422351
d2 = argvars[1].vval.v_dict;
2343-
if (d1 != NULL && !value_check_lock(d1->dv_lock, arg_errmsg, TRUE)
2344-
&& d2 != NULL)
2352+
if (!value_check_lock(d1->dv_lock, arg_errmsg, TRUE) && d2 != NULL)
23452353
{
23462354
// Check the third argument.
23472355
if (argvars[2].v_type != VAR_UNKNOWN)

src/testdir/test_vim9_assign.vim

Lines changed: 49 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -231,10 +231,14 @@ def Test_extend_list()
231231
var l: list<number>
232232
l += [123]
233233
assert_equal([123], l)
234+
END
235+
CheckScriptSuccess(lines)
234236

235-
var d: dict<number>
236-
d['one'] = 1
237-
assert_equal(#{one: 1}, d)
237+
lines =<< trim END
238+
vim9script
239+
var list: list<string>
240+
extend(list, ['x'])
241+
assert_equal(['x'], list)
238242
END
239243
CheckScriptSuccess(lines)
240244

@@ -249,6 +253,48 @@ def Test_extend_list()
249253
assert_equal(['a', 'b'], list)
250254
END
251255
CheckScriptSuccess(lines)
256+
257+
lines =<< trim END
258+
vim9script
259+
var l: list<string> = test_null_list()
260+
extend(l, ['x'])
261+
assert_equal(['x'], l)
262+
END
263+
CheckScriptSuccess(lines)
264+
265+
lines =<< trim END
266+
vim9script
267+
extend(test_null_list(), ['x'])
268+
END
269+
CheckScriptFailure(lines, 'E1134:', 2)
270+
enddef
271+
272+
def Test_extend_dict()
273+
var lines =<< trim END
274+
vim9script
275+
var d: dict<number>
276+
extend(d, #{a: 1})
277+
assert_equal(#{a: 1}, d)
278+
279+
var d2: dict<number>
280+
d2['one'] = 1
281+
assert_equal(#{one: 1}, d2)
282+
END
283+
CheckScriptSuccess(lines)
284+
285+
lines =<< trim END
286+
vim9script
287+
var d: dict<string> = test_null_dict()
288+
extend(d, #{a: 'x'})
289+
assert_equal(#{a: 'x'}, d)
290+
END
291+
CheckScriptSuccess(lines)
292+
293+
lines =<< trim END
294+
vim9script
295+
extend(test_null_dict(), #{a: 'x'})
296+
END
297+
CheckScriptFailure(lines, 'E1133:', 2)
252298
enddef
253299

254300
def Test_single_letter_vars()

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+
1949,
753755
/**/
754756
1948,
755757
/**/

0 commit comments

Comments
 (0)