summaryrefslogtreecommitdiff
path: root/src/viminfo.c
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2020-06-07 16:08:08 +0200
committerBram Moolenaar <Bram@vim.org>2020-06-07 16:08:08 +0200
commit5b157fe2edfdce5f77080aeac2b4a03f39eb1c1a (patch)
treee2757dfeb60d92934e3cd0900d9eb43769389f56 /src/viminfo.c
parent673fc3e23f09095d17f0095c4323958041b2d0d2 (diff)
downloadvim-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.c30
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;