summaryrefslogtreecommitdiffstats
path: root/src/charset.c
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2022-08-05 11:45:17 +0100
committerBram Moolenaar <Bram@vim.org>2022-08-05 11:45:17 +0100
commit2f83cc4cfa56750c91eb6daa8fde319bca032d18 (patch)
treeff9fe020346871dd62e92db9df62d9355d64c2f0 /src/charset.c
parent206fce307b265f7f6c6290b623a80c1d846dd131 (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.c58
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;