diff options
author | Bram Moolenaar <Bram@vim.org> | 2020-06-07 16:08:08 +0200 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2020-06-07 16:08:08 +0200 |
commit | 5b157fe2edfdce5f77080aeac2b4a03f39eb1c1a (patch) | |
tree | e2757dfeb60d92934e3cd0900d9eb43769389f56 /src/viminfo.c | |
parent | 673fc3e23f09095d17f0095c4323958041b2d0d2 (diff) | |
download | vim-git-5b157fe2edfdce5f77080aeac2b4a03f39eb1c1a.tar.gz |
patch 8.2.0920: writing viminfo fails with a circular referencev8.2.0920
Problem: Writing viminfo fails with a circular reference.
Solution: Use copyID to detect the cycle. (closes #6217)
Diffstat (limited to 'src/viminfo.c')
-rw-r--r-- | src/viminfo.c | 30 |
1 files changed, 28 insertions, 2 deletions
diff --git a/src/viminfo.c b/src/viminfo.c index b014d7f21..4f26348a2 100644 --- a/src/viminfo.c +++ b/src/viminfo.c @@ -1337,8 +1337,34 @@ write_viminfo_varlist(FILE *fp) case VAR_STRING: s = "STR"; break; case VAR_NUMBER: s = "NUM"; break; case VAR_FLOAT: s = "FLO"; break; - case VAR_DICT: s = "DIC"; break; - case VAR_LIST: s = "LIS"; break; + case VAR_DICT: + { + 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_BOOL: s = "XPL"; break; // backwards compat. case VAR_SPECIAL: s = "XPL"; break; |