]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
patch 9.0.1606: using freed memory when 'foldcolumn' is set v9.0.1606
authorzeertzjq <zeertzjq@outlook.com>
Sun, 4 Jun 2023 17:46:28 +0000 (18:46 +0100)
committerBram Moolenaar <Bram@vim.org>
Sun, 4 Jun 2023 17:46:28 +0000 (18:46 +0100)
Problem:    Using freed memory when 'foldcolumn' is set.
Solution:   Save extra pointer to free it later. (closes #12492)

src/drawline.c
src/testdir/test_fold.vim
src/version.c

index 2fbfe452cd7f93d157a24bac219d072a81c7e5c6..848b3ae89200a020c2aa2c2279dfbd66f26ca25f 100644 (file)
@@ -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;
 }
index e0119c4975e9dda79c49ddb63f4a8dbadf2f99cf..398a0c2d71069922f8ca0d3fa69046028da47a0d 100644 (file)
@@ -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
index 335e3bd705b2f67759986a40ca1a529f18d2ff1d..b17b01b6d1d18fbe44f245da933e03e5dba1a960 100644 (file)
@@ -695,6 +695,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1606,
 /**/
     1605,
 /**/