Mercurial > vim
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) |