changeset 19364:b7abf45d527b v8.2.0240

patch 8.2.0240: using memory after it was freed Commit: https://github.com/vim/vim/commit/408030e8d053fe1c871b2fc366363a30ed98c889 Author: Bram Moolenaar <Bram@vim.org> Date: Mon Feb 10 22:44:32 2020 +0100 patch 8.2.0240: using memory after it was freed Problem: Using memory after it was freed. (Dominique Pelle) Solution: Do not mix converion buffer with other buffer.
author Bram Moolenaar <Bram@vim.org>
date Mon, 10 Feb 2020 22:45:04 +0100
parents 9a3f1714c40d
children 91e051377c65
files src/version.c src/vim.h src/viminfo.c
diffstat 3 files changed, 23 insertions(+), 17 deletions(-) [+]
line wrap: on
line diff
--- a/src/version.c
+++ b/src/version.c
@@ -743,6 +743,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    240,
+/**/
     239,
 /**/
     238,
--- a/src/vim.h
+++ b/src/vim.h
@@ -1129,20 +1129,6 @@ extern int (*dyn_libintl_wputenv)(const 
 #define VIMINFO_VERSION_WITH_REGISTERS 3
 #define VIMINFO_VERSION_WITH_MARKS 4
 
-typedef enum {
-    BVAL_NR,
-    BVAL_STRING,
-    BVAL_EMPTY
-} btype_T;
-
-typedef struct {
-    btype_T	bv_type;
-    long	bv_nr;
-    char_u	*bv_string;
-    int		bv_len;		// length of bv_string
-    int		bv_allocated;	// bv_string was allocated
-} bval_T;
-
 /*
  * Values for do_tag().
  */
--- a/src/viminfo.c
+++ b/src/viminfo.c
@@ -26,6 +26,21 @@ typedef struct
     garray_T	vir_barlines;	// lines starting with |
 } vir_T;
 
+typedef enum {
+    BVAL_NR,
+    BVAL_STRING,
+    BVAL_EMPTY
+} btype_T;
+
+typedef struct {
+    btype_T	bv_type;
+    long	bv_nr;
+    char_u	*bv_string;
+    char_u	*bv_tofree;	// free later when not NULL
+    int		bv_len;		// length of bv_string
+    int		bv_allocated;	// bv_string was allocated
+} bval_T;
+
 #if defined(FEAT_VIMINFO) || defined(PROTO)
 
 static int  viminfo_errcnt;
@@ -1087,22 +1102,24 @@ barline_parse(vir_T *virp, char_u *text,
 	    s[len] = NUL;
 
 	    converted = FALSE;
+	    value->bv_tofree = NULL;
 	    if (virp->vir_conv.vc_type != CONV_NONE && *s != NUL)
 	    {
 		sconv = string_convert(&virp->vir_conv, s, NULL);
 		if (sconv != NULL)
 		{
 		    if (s == buf)
-			vim_free(s);
+			// the converted string is stored in bv_string and
+			// freed later, also need to free "buf" later
+			value->bv_tofree = buf;
 		    s = sconv;
-		    buf = s;
 		    converted = TRUE;
 		}
 	    }
 
 	    // Need to copy in allocated memory if the string wasn't allocated
 	    // above and we did allocate before, thus vir_line may change.
-	    if (s != buf && allocated)
+	    if (s != buf && allocated && !converted)
 		s = vim_strsave(s);
 	    value->bv_string = s;
 	    value->bv_type = BVAL_STRING;
@@ -2747,6 +2764,7 @@ read_viminfo_barline(vir_T *virp, int go
 	    vp = (bval_T *)values.ga_data + i;
 	    if (vp->bv_type == BVAL_STRING && vp->bv_allocated)
 		vim_free(vp->bv_string);
+	    vim_free(vp->bv_tofree);
 	}
 	ga_clear(&values);
     }