mirror of
https://github.com/vim/vim.git
synced 2025-09-25 03:54:15 -04:00
patch 8.2.0920: writing viminfo fails with a circular reference
Problem: Writing viminfo fails with a circular reference. Solution: Use copyID to detect the cycle. (closes #6217)
This commit is contained in:
@@ -91,6 +91,28 @@ func Test_global_vars()
|
|||||||
set viminfo-=!
|
set viminfo-=!
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
|
func Test_global_vars_with_circular_reference()
|
||||||
|
let g:MY_GLOBAL_LIST = []
|
||||||
|
call add(g:MY_GLOBAL_LIST, g:MY_GLOBAL_LIST)
|
||||||
|
let g:MY_GLOBAL_DICT = {}
|
||||||
|
let g:MY_GLOBAL_DICT['self'] = g:MY_GLOBAL_DICT
|
||||||
|
|
||||||
|
set viminfo='100,<50,s10,h,!,nviminfo
|
||||||
|
wv! Xviminfo
|
||||||
|
call assert_equal(v:errmsg, '')
|
||||||
|
|
||||||
|
unlet g:MY_GLOBAL_LIST
|
||||||
|
unlet g:MY_GLOBAL_DICT
|
||||||
|
|
||||||
|
rv! Xviminfo
|
||||||
|
call assert_equal(v:errmsg, '')
|
||||||
|
call assert_true(!exists('g:MY_GLOBAL_LIST'))
|
||||||
|
call assert_true(!exists('g:MY_GLOBAL_DICT'))
|
||||||
|
|
||||||
|
call delete('Xviminfo')
|
||||||
|
set viminfo-=!
|
||||||
|
endfunc
|
||||||
|
|
||||||
func Test_cmdline_history()
|
func Test_cmdline_history()
|
||||||
call histdel(':')
|
call histdel(':')
|
||||||
call test_settime(11)
|
call test_settime(11)
|
||||||
|
@@ -754,6 +754,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
920,
|
||||||
/**/
|
/**/
|
||||||
919,
|
919,
|
||||||
/**/
|
/**/
|
||||||
|
@@ -1337,8 +1337,34 @@ write_viminfo_varlist(FILE *fp)
|
|||||||
case VAR_STRING: s = "STR"; break;
|
case VAR_STRING: s = "STR"; break;
|
||||||
case VAR_NUMBER: s = "NUM"; break;
|
case VAR_NUMBER: s = "NUM"; break;
|
||||||
case VAR_FLOAT: s = "FLO"; break;
|
case VAR_FLOAT: s = "FLO"; break;
|
||||||
case VAR_DICT: s = "DIC"; break;
|
case VAR_DICT:
|
||||||
case VAR_LIST: s = "LIS"; break;
|
{
|
||||||
|
dict_T *di = this_var->di_tv.vval.v_dict;
|
||||||
|
int copyID = get_copyID();
|
||||||
|
|
||||||
|
s = "DIC";
|
||||||
|
if (di != NULL && !set_ref_in_ht(
|
||||||
|
&di->dv_hashtab, copyID, NULL)
|
||||||
|
&& di->dv_copyID == copyID)
|
||||||
|
// has a circular reference, can't turn the
|
||||||
|
// value into a string
|
||||||
|
continue;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case VAR_LIST:
|
||||||
|
{
|
||||||
|
list_T *l = this_var->di_tv.vval.v_list;
|
||||||
|
int copyID = get_copyID();
|
||||||
|
|
||||||
|
s = "LIS";
|
||||||
|
if (l != NULL && !set_ref_in_list_items(
|
||||||
|
l, copyID, NULL)
|
||||||
|
&& l->lv_copyID == copyID)
|
||||||
|
// has a circular reference, can't turn the
|
||||||
|
// value into a string
|
||||||
|
continue;
|
||||||
|
break;
|
||||||
|
}
|
||||||
case VAR_BLOB: s = "BLO"; break;
|
case VAR_BLOB: s = "BLO"; break;
|
||||||
case VAR_BOOL: s = "XPL"; break; // backwards compat.
|
case VAR_BOOL: s = "XPL"; break; // backwards compat.
|
||||||
case VAR_SPECIAL: s = "XPL"; break;
|
case VAR_SPECIAL: s = "XPL"; break;
|
||||||
|
Reference in New Issue
Block a user