diff src/viminfo.c @ 20735:298ef749e5fb v8.2.0920

patch 8.2.0920: writing viminfo fails with a circular reference Commit: https://github.com/vim/vim/commit/5b157fe2edfdce5f77080aeac2b4a03f39eb1c1a Author: Bram Moolenaar <Bram@vim.org> Date: Sun Jun 7 16:08:08 2020 +0200 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 https://github.com/vim/vim/issues/6217)
author Bram Moolenaar <Bram@vim.org>
date Sun, 07 Jun 2020 16:15:03 +0200
parents 1f42c49c3d29
children 93dae47699fb
line wrap: on
line diff
--- 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;