diff options
author | zeertzjq <zeertzjq@outlook.com> | 2023-06-05 06:58:14 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-06-05 06:58:14 +0800 |
commit | 67827edeef5ce3718c40c83ccca07dd1854a0f16 (patch) | |
tree | 26aedfd4ae2977d74e391f351b63179ca31ae5d2 | |
parent | fdc8e966a9183c08f2afec0817d03b7417a883b3 (diff) | |
download | rneovim-67827edeef5ce3718c40c83ccca07dd1854a0f16.tar.gz rneovim-67827edeef5ce3718c40c83ccca07dd1854a0f16.tar.bz2 rneovim-67827edeef5ce3718c40c83ccca07dd1854a0f16.zip |
vim-patch:9.0.1606: using freed memory when 'foldcolumn' is set (#23906)
Problem: Using freed memory when 'foldcolumn' is set.
Solution: Save extra pointer to free it later. (closes vim/vim#12492)
https://github.com/vim/vim/commit/58e1e010454113a7c8a9b0327c54d2ee7d73d2fd
-rw-r--r-- | src/nvim/drawline.c | 10 | ||||
-rw-r--r-- | test/old/testdir/test_fold.vim | 14 |
2 files changed, 23 insertions, 1 deletions
diff --git a/src/nvim/drawline.c b/src/nvim/drawline.c index 49c4b6f32a..ff14ae0e41 100644 --- a/src/nvim/drawline.c +++ b/src/nvim/drawline.c @@ -111,6 +111,7 @@ typedef struct { // saved "extra" items for when draw_state becomes WL_LINE (again) int saved_n_extra; char *saved_p_extra; + char *saved_p_extra_free; bool saved_extra_for_extmark; int saved_c_extra; int saved_c_final; @@ -995,6 +996,9 @@ static void win_line_start(win_T *wp, winlinevars_T *wlv, bool save_extra) wlv->draw_state = WL_START; wlv->saved_n_extra = wlv->n_extra; wlv->saved_p_extra = wlv->p_extra; + xfree(wlv->saved_p_extra_free); + wlv->saved_p_extra_free = wlv->p_extra_free; + wlv->p_extra_free = NULL; wlv->saved_extra_for_extmark = wlv->extra_for_extmark; wlv->saved_c_extra = wlv->c_extra; wlv->saved_c_final = wlv->c_final; @@ -1011,10 +1015,13 @@ static void win_line_continue(winlinevars_T *wlv) // Continue item from end of wrapped line. wlv->n_extra = wlv->saved_n_extra; wlv->saved_n_extra = 0; - wlv->extra_for_extmark = wlv->saved_extra_for_extmark; wlv->c_extra = wlv->saved_c_extra; wlv->c_final = wlv->saved_c_final; wlv->p_extra = wlv->saved_p_extra; + xfree(wlv->p_extra_free); + wlv->p_extra_free = wlv->saved_p_extra_free; + wlv->saved_p_extra_free = NULL; + wlv->extra_for_extmark = wlv->saved_extra_for_extmark; wlv->char_attr = wlv->saved_char_attr; } else { wlv->char_attr = 0; @@ -3138,5 +3145,6 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl kv_destroy(virt_lines); xfree(wlv.p_extra_free); + xfree(wlv.saved_p_extra_free); return wlv.row; } diff --git a/test/old/testdir/test_fold.vim b/test/old/testdir/test_fold.vim index 2f5c93ca2d..ccd1bfecf8 100644 --- a/test/old/testdir/test_fold.vim +++ b/test/old/testdir/test_fold.vim @@ -1555,4 +1555,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 |