diff options
author | Bram Moolenaar <Bram@vim.org> | 2022-08-05 11:45:17 +0100 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2022-08-05 11:45:17 +0100 |
commit | 2f83cc4cfa56750c91eb6daa8fde319bca032d18 (patch) | |
tree | ff9fe020346871dd62e92db9df62d9355d64c2f0 /src/charset.c | |
parent | 206fce307b265f7f6c6290b623a80c1d846dd131 (diff) |
patch 9.0.0142: crash when adding and removing virtual textv9.0.0142
Problem: Crash when adding and removing virtual text. (Ben Jackson)
Solution: Check that the text of the text property still exists.
Diffstat (limited to 'src/charset.c')
-rw-r--r-- | src/charset.c | 58 |
1 files changed, 32 insertions, 26 deletions
diff --git a/src/charset.c b/src/charset.c index 7ed1fd1bd7..c32044adb5 100644 --- a/src/charset.c +++ b/src/charset.c @@ -1129,43 +1129,49 @@ win_lbr_chartabsize( # ifdef FEAT_PROP_POPUP if (cts->cts_has_prop_with_text) { - int i; - int col = (int)(s - line); + int i; + int col = (int)(s - line); + garray_T *gap = &wp->w_buffer->b_textprop_text; for (i = 0; i < cts->cts_text_prop_count; ++i) { textprop_T *tp = cts->cts_text_props + i; + // Watch out for the text being deleted. "cts_text_props" is a + // copy, the text prop may actually have been removed from the line. if (tp->tp_id < 0 - && ((tp->tp_col - 1 >= col && tp->tp_col - 1 < col + size - && -tp->tp_id <= wp->w_buffer->b_textprop_text.ga_len) - || (tp->tp_col == MAXCOL && (s[0] == NUL || s[1] == NUL) - && cts->cts_with_trailing))) + && ((tp->tp_col - 1 >= col && tp->tp_col - 1 < col + size) + || (tp->tp_col == MAXCOL && (s[0] == NUL || s[1] == NUL) + && cts->cts_with_trailing)) + && -tp->tp_id - 1 < gap->ga_len) { - char_u *p = ((char_u **)wp->w_buffer->b_textprop_text.ga_data)[ - -tp->tp_id - 1]; - int cells = vim_strsize(p); + char_u *p = ((char_u **)gap->ga_data)[-tp->tp_id - 1]; - added = wp->w_width - (vcol + size) % wp->w_width; - if (tp->tp_col == MAXCOL) + if (p != NULL) { - int below = (tp->tp_flags & TP_FLAG_ALIGN_BELOW); - int wrap = (tp->tp_flags & TP_FLAG_WRAP); - int len = (int)STRLEN(p); - int n_used = len; - - // Keep in sync with where textprop_size_after_trunc() is - // called in win_line(). - if (!wrap) - cells = textprop_size_after_trunc(wp, + int cells = vim_strsize(p); + + added = wp->w_width - (vcol + size) % wp->w_width; + if (tp->tp_col == MAXCOL) + { + int below = (tp->tp_flags & TP_FLAG_ALIGN_BELOW); + int wrap = (tp->tp_flags & TP_FLAG_WRAP); + int len = (int)STRLEN(p); + int n_used = len; + + // Keep in sync with where textprop_size_after_trunc() + // is called in win_line(). + if (!wrap) + cells = textprop_size_after_trunc(wp, below, added, p, &n_used); - // right-aligned does not really matter here, same as - // "after" - if (below) - cells += wp->w_width - (vcol + size) % wp->w_width; + // right-aligned does not really matter here, same as + // "after" + if (below) + cells += wp->w_width - (vcol + size) % wp->w_width; + } + cts->cts_cur_text_width += cells; + size += cells; } - cts->cts_cur_text_width += cells; - size += cells; } if (tp->tp_col - 1 > col) break; |