comparison src/charset.c @ 29603:8f01d250793a v9.0.0142

patch 9.0.0142: crash when adding and removing virtual text Commit: https://github.com/vim/vim/commit/2f83cc4cfa56750c91eb6daa8fde319bca032d18 Author: Bram Moolenaar <Bram@vim.org> Date: Fri Aug 5 11:45:17 2022 +0100 patch 9.0.0142: crash when adding and removing virtual text Problem: Crash when adding and removing virtual text. (Ben Jackson) Solution: Check that the text of the text property still exists.
author Bram Moolenaar <Bram@vim.org>
date Fri, 05 Aug 2022 13:00:03 +0200
parents f2d7f20d83c3
children 0340a59e04ca
comparison
equal deleted inserted replaced
29602:093466b0c903 29603:8f01d250793a
1127 size = win_chartabsize(wp, s, vcol); 1127 size = win_chartabsize(wp, s, vcol);
1128 1128
1129 # ifdef FEAT_PROP_POPUP 1129 # ifdef FEAT_PROP_POPUP
1130 if (cts->cts_has_prop_with_text) 1130 if (cts->cts_has_prop_with_text)
1131 { 1131 {
1132 int i; 1132 int i;
1133 int col = (int)(s - line); 1133 int col = (int)(s - line);
1134 garray_T *gap = &wp->w_buffer->b_textprop_text;
1134 1135
1135 for (i = 0; i < cts->cts_text_prop_count; ++i) 1136 for (i = 0; i < cts->cts_text_prop_count; ++i)
1136 { 1137 {
1137 textprop_T *tp = cts->cts_text_props + i; 1138 textprop_T *tp = cts->cts_text_props + i;
1138 1139
1140 // Watch out for the text being deleted. "cts_text_props" is a
1141 // copy, the text prop may actually have been removed from the line.
1139 if (tp->tp_id < 0 1142 if (tp->tp_id < 0
1140 && ((tp->tp_col - 1 >= col && tp->tp_col - 1 < col + size 1143 && ((tp->tp_col - 1 >= col && tp->tp_col - 1 < col + size)
1141 && -tp->tp_id <= wp->w_buffer->b_textprop_text.ga_len) 1144 || (tp->tp_col == MAXCOL && (s[0] == NUL || s[1] == NUL)
1142 || (tp->tp_col == MAXCOL && (s[0] == NUL || s[1] == NUL) 1145 && cts->cts_with_trailing))
1143 && cts->cts_with_trailing))) 1146 && -tp->tp_id - 1 < gap->ga_len)
1144 { 1147 {
1145 char_u *p = ((char_u **)wp->w_buffer->b_textprop_text.ga_data)[ 1148 char_u *p = ((char_u **)gap->ga_data)[-tp->tp_id - 1];
1146 -tp->tp_id - 1]; 1149
1147 int cells = vim_strsize(p); 1150 if (p != NULL)
1148
1149 added = wp->w_width - (vcol + size) % wp->w_width;
1150 if (tp->tp_col == MAXCOL)
1151 { 1151 {
1152 int below = (tp->tp_flags & TP_FLAG_ALIGN_BELOW); 1152 int cells = vim_strsize(p);
1153 int wrap = (tp->tp_flags & TP_FLAG_WRAP); 1153
1154 int len = (int)STRLEN(p); 1154 added = wp->w_width - (vcol + size) % wp->w_width;
1155 int n_used = len; 1155 if (tp->tp_col == MAXCOL)
1156 1156 {
1157 // Keep in sync with where textprop_size_after_trunc() is 1157 int below = (tp->tp_flags & TP_FLAG_ALIGN_BELOW);
1158 // called in win_line(). 1158 int wrap = (tp->tp_flags & TP_FLAG_WRAP);
1159 if (!wrap) 1159 int len = (int)STRLEN(p);
1160 cells = textprop_size_after_trunc(wp, 1160 int n_used = len;
1161
1162 // Keep in sync with where textprop_size_after_trunc()
1163 // is called in win_line().
1164 if (!wrap)
1165 cells = textprop_size_after_trunc(wp,
1161 below, added, p, &n_used); 1166 below, added, p, &n_used);
1162 // right-aligned does not really matter here, same as 1167 // right-aligned does not really matter here, same as
1163 // "after" 1168 // "after"
1164 if (below) 1169 if (below)
1165 cells += wp->w_width - (vcol + size) % wp->w_width; 1170 cells += wp->w_width - (vcol + size) % wp->w_width;
1171 }
1172 cts->cts_cur_text_width += cells;
1173 size += cells;
1166 } 1174 }
1167 cts->cts_cur_text_width += cells;
1168 size += cells;
1169 } 1175 }
1170 if (tp->tp_col - 1 > col) 1176 if (tp->tp_col - 1 > col)
1171 break; 1177 break;
1172 } 1178 }
1173 } 1179 }