comparison src/viminfo.c @ 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 94eda51ba9ba
children 9daed26b788b
comparison
equal deleted inserted replaced
19363:9a3f1714c40d 19364:b7abf45d527b
23 FILE *vir_fd; // file descriptor 23 FILE *vir_fd; // file descriptor
24 vimconv_T vir_conv; // encoding conversion 24 vimconv_T vir_conv; // encoding conversion
25 int vir_version; // viminfo version detected or -1 25 int vir_version; // viminfo version detected or -1
26 garray_T vir_barlines; // lines starting with | 26 garray_T vir_barlines; // lines starting with |
27 } vir_T; 27 } vir_T;
28
29 typedef enum {
30 BVAL_NR,
31 BVAL_STRING,
32 BVAL_EMPTY
33 } btype_T;
34
35 typedef struct {
36 btype_T bv_type;
37 long bv_nr;
38 char_u *bv_string;
39 char_u *bv_tofree; // free later when not NULL
40 int bv_len; // length of bv_string
41 int bv_allocated; // bv_string was allocated
42 } bval_T;
28 43
29 #if defined(FEAT_VIMINFO) || defined(PROTO) 44 #if defined(FEAT_VIMINFO) || defined(PROTO)
30 45
31 static int viminfo_errcnt; 46 static int viminfo_errcnt;
32 47
1085 } 1100 }
1086 ++p; 1101 ++p;
1087 s[len] = NUL; 1102 s[len] = NUL;
1088 1103
1089 converted = FALSE; 1104 converted = FALSE;
1105 value->bv_tofree = NULL;
1090 if (virp->vir_conv.vc_type != CONV_NONE && *s != NUL) 1106 if (virp->vir_conv.vc_type != CONV_NONE && *s != NUL)
1091 { 1107 {
1092 sconv = string_convert(&virp->vir_conv, s, NULL); 1108 sconv = string_convert(&virp->vir_conv, s, NULL);
1093 if (sconv != NULL) 1109 if (sconv != NULL)
1094 { 1110 {
1095 if (s == buf) 1111 if (s == buf)
1096 vim_free(s); 1112 // the converted string is stored in bv_string and
1113 // freed later, also need to free "buf" later
1114 value->bv_tofree = buf;
1097 s = sconv; 1115 s = sconv;
1098 buf = s;
1099 converted = TRUE; 1116 converted = TRUE;
1100 } 1117 }
1101 } 1118 }
1102 1119
1103 // Need to copy in allocated memory if the string wasn't allocated 1120 // Need to copy in allocated memory if the string wasn't allocated
1104 // above and we did allocate before, thus vir_line may change. 1121 // above and we did allocate before, thus vir_line may change.
1105 if (s != buf && allocated) 1122 if (s != buf && allocated && !converted)
1106 s = vim_strsave(s); 1123 s = vim_strsave(s);
1107 value->bv_string = s; 1124 value->bv_string = s;
1108 value->bv_type = BVAL_STRING; 1125 value->bv_type = BVAL_STRING;
1109 value->bv_len = len; 1126 value->bv_len = len;
1110 value->bv_allocated = allocated || converted; 1127 value->bv_allocated = allocated || converted;
2745 for (i = 0; i < values.ga_len; ++i) 2762 for (i = 0; i < values.ga_len; ++i)
2746 { 2763 {
2747 vp = (bval_T *)values.ga_data + i; 2764 vp = (bval_T *)values.ga_data + i;
2748 if (vp->bv_type == BVAL_STRING && vp->bv_allocated) 2765 if (vp->bv_type == BVAL_STRING && vp->bv_allocated)
2749 vim_free(vp->bv_string); 2766 vim_free(vp->bv_string);
2767 vim_free(vp->bv_tofree);
2750 } 2768 }
2751 ga_clear(&values); 2769 ga_clear(&values);
2752 } 2770 }
2753 2771
2754 if (read_next) 2772 if (read_next)