summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorzeertzjq <zeertzjq@outlook.com>2023-06-04 18:46:28 +0100
committerBram Moolenaar <Bram@vim.org>2023-06-04 18:46:28 +0100
commit58e1e010454113a7c8a9b0327c54d2ee7d73d2fd (patch)
treea9ffdc54b4895a395ca6a114d82992f139def24c
parent114ec813b3a7f70d7a1c86e87226f5273e9d1def (diff)
patch 9.0.1606: using freed memory when 'foldcolumn' is setv9.0.1606
Problem: Using freed memory when 'foldcolumn' is set. Solution: Save extra pointer to free it later. (closes #12492)
-rw-r--r--src/drawline.c10
-rw-r--r--src/testdir/test_fold.vim14
-rw-r--r--src/version.c2
3 files changed, 25 insertions, 1 deletions
diff --git a/src/drawline.c b/src/drawline.c
index 2fbfe452cd..848b3ae892 100644
--- a/src/drawline.c
+++ b/src/drawline.c
@@ -150,6 +150,7 @@ typedef struct {
// saved "extra" items for when draw_state becomes WL_LINE (again)
int saved_n_extra;
char_u *saved_p_extra;
+ char_u *saved_p_extra_free;
int saved_extra_attr;
int saved_n_attr_skip;
int saved_extra_for_textprop;
@@ -230,7 +231,7 @@ handle_foldcolumn(win_T *wp, winlinevars_T *wlv)
return;
wlv->n_extra = (int)fill_foldcolumn(wlv->p_extra_free,
- wp, FALSE, wlv->lnum);
+ wp, FALSE, wlv->lnum);
wlv->p_extra_free[wlv->n_extra] = NUL;
wlv->p_extra = wlv->p_extra_free;
wlv->c_extra = NUL;
@@ -979,6 +980,9 @@ win_line_start(win_T *wp UNUSED, winlinevars_T *wlv, int save_extra)
wlv->draw_state = WL_START;
wlv->saved_n_extra = wlv->n_extra;
wlv->saved_p_extra = wlv->p_extra;
+ vim_free(wlv->saved_p_extra_free);
+ wlv->saved_p_extra_free = wlv->p_extra_free;
+ wlv->p_extra_free = NULL;
wlv->saved_extra_attr = wlv->extra_attr;
wlv->saved_n_attr_skip = wlv->n_attr_skip;
wlv->saved_extra_for_textprop = wlv->extra_for_textprop;
@@ -1015,6 +1019,9 @@ win_line_continue(winlinevars_T *wlv)
wlv->c_extra = wlv->saved_c_extra;
wlv->c_final = wlv->saved_c_final;
wlv->p_extra = wlv->saved_p_extra;
+ vim_free(wlv->p_extra_free);
+ wlv->p_extra_free = wlv->saved_p_extra_free;
+ wlv->saved_p_extra_free = NULL;
wlv->extra_attr = wlv->saved_extra_attr;
wlv->n_attr_skip = wlv->saved_n_attr_skip;
wlv->extra_for_textprop = wlv->saved_extra_for_textprop;
@@ -4119,5 +4126,6 @@ win_line(
#endif
vim_free(wlv.p_extra_free);
+ vim_free(wlv.saved_p_extra_free);
return wlv.row;
}
diff --git a/src/testdir/test_fold.vim b/src/testdir/test_fold.vim
index e0119c4975..398a0c2d71 100644
--- a/src/testdir/test_fold.vim
+++ b/src/testdir/test_fold.vim
@@ -1755,4 +1755,18 @@ func Test_fold_screenrow_motion()
call assert_equal(1, line('.'))
endfunc
+" This was using freed memory
+func Test_foldcolumn_linebreak_control_char()
+ CheckFeature linebreak
+
+ 5vnew
+ setlocal foldcolumn=1 linebreak
+ call setline(1, "aaa\<C-A>b")
+ redraw
+ call assert_equal([' aaa^', ' Ab '], ScreenLines([1, 2], 5))
+ call assert_equal(screenattr(1, 5), screenattr(2, 2))
+
+ bwipe!
+endfunc
+
" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/version.c b/src/version.c
index 335e3bd705..b17b01b6d1 100644
--- a/src/version.c
+++ b/src/version.c
@@ -696,6 +696,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 1606,
+/**/
1605,
/**/
1604,