# HG changeset patch # User Bram Moolenaar # Date 1594827903 -7200 # Node ID 608f674c6035c126fe60713ccfd64360a8d60892 # Parent 84baaef59d1976304e951983c71e40c449a40c54 patch 8.2.1220: memory access error when dragging a popup window Commit: https://github.com/vim/vim/commit/452143c6bf0dcf76ef415281b0e4fbc3edff4b6b Author: Bram Moolenaar Date: Wed Jul 15 17:38:21 2020 +0200 patch 8.2.1220: memory access error when dragging a popup window Problem: memory access error when dragging a popup window over a buffer with folding. Solution: Avoid going over the end of the cache. (closes #6438) diff --git a/src/mouse.c b/src/mouse.c --- a/src/mouse.c +++ b/src/mouse.c @@ -2839,10 +2839,10 @@ check_termcode_mouse( /* * Compute the buffer line position from the screen position "rowp" / "colp" in * window "win". - * "plines_cache" can be NULL (no cache) or an array with "win->w_height" - * entries that caches the plines_win() result from a previous call. Entry is - * zero if not computed yet. There must be no text or setting changes since - * the entry is put in the cache. + * "plines_cache" can be NULL (no cache) or an array with "Rows" entries that + * caches the plines_win() result from a previous call. Entry is zero if not + * computed yet. There must be no text or setting changes since the entry is + * put in the cache. * Returns TRUE if the position is below the last line. */ int @@ -2871,7 +2871,10 @@ mouse_comp_pos( { int cache_idx = lnum - win->w_topline; - if (plines_cache != NULL && plines_cache[cache_idx] > 0) + // Only "Rows" lines are cached, with folding we'll run out of entries + // and use the slow way. + if (plines_cache != NULL && cache_idx < Rows + && plines_cache[cache_idx] > 0) count = plines_cache[cache_idx]; else { @@ -2892,7 +2895,7 @@ mouse_comp_pos( else #endif count = plines_win(win, lnum, TRUE); - if (plines_cache != NULL) + if (plines_cache != NULL && cache_idx < Rows) plines_cache[cache_idx] = count; } if (count > row) diff --git a/src/testdir/dumps/Test_popupwin_term_01.dump b/src/testdir/dumps/Test_popupwin_term_01.dump --- a/src/testdir/dumps/Test_popupwin_term_01.dump +++ b/src/testdir/dumps/Test_popupwin_term_01.dump @@ -3,8 +3,14 @@ @34|╔+0#0000001#ffd7ff255|═@3|╗| +0#0000000#ffffff0@34 @34|║+0#0000001#ffd7ff255|1@3|║| +0#0000000#ffffff0@34 |!+0#ffffff16#00e0003|/|b|i|n|/|s|h| |[|r|u|n@1|i|n|g|]| @15|║+0#0000001#ffd7ff255|2@3|║| +0#ffffff16#00e0003@34 -> +0#0000000#ffffff0@33|╚+0#0000001#ffd7ff255|═@3|⇲| +0#0000000#ffffff0@34 -|~+0#4040ff13&| @73 -|~| @73 -|[+3#0000000&|N|o| |N|a|m|e|]| @65 +>++0#0000e05#a8a8a8255|-@1| |1@1| |l|i|n|e|s|:| |f|o|l|d| |-@14|╚+0#0000001#ffd7ff255|═@3|⇲|-+0#0000e05#a8a8a8255@34 +|1+0#0000000#ffffff0@1| @72 +|++0#0000e05#a8a8a8255|-@1| |1@1| |l|i|n|e|s|:| |f|o|l|d| |-@55 +|2+0#0000000#ffffff0|3| @72 +|++0#0000e05#a8a8a8255|-@1| |1@1| |l|i|n|e|s|:| |f|o|l|d| |-@55 +|3+0#0000000#ffffff0|5| @72 +|++0#0000e05#a8a8a8255|-@1| |1@1| |l|i|n|e|s|:| |f|o|l|d| |-@55 +|4+0#0000000#ffffff0|7| @72 +|++0#0000e05#a8a8a8255|-@1| |1@1| |l|i|n|e|s|:| |f|o|l|d| |-@55 +|[+3#0000000#ffffff0|N|o| |N|a|m|e|]| |[|+|]| @61 | +0&&@74 diff --git a/src/testdir/dumps/Test_popupwin_term_02.dump b/src/testdir/dumps/Test_popupwin_term_02.dump --- a/src/testdir/dumps/Test_popupwin_term_02.dump +++ b/src/testdir/dumps/Test_popupwin_term_02.dump @@ -3,8 +3,14 @@ @14|╔+0#0000001#ffd7ff255|═@3|╗| +0#0000000#ffffff0@54 @14|║+0#0000001#ffd7ff255|1@3|║| +0#0000000#ffffff0@54 |!+0#ffffff16#00e0003|/|b|i|n|/|s|h| |[|r|u|n@1|║+0#0000001#ffd7ff255|2@3|║| +0#ffffff16#00e0003@54 -> +0#0000000#ffffff0@13|╚+0#0000001#ffd7ff255|═@3|⇲| +0#0000000#ffffff0@54 -|~+0#4040ff13&| @73 -|~| @73 -|[+3#0000000&|N|o| |N|a|m|e|]| @65 -|:+0&&|c|a|l@1| |D|r|a|g|i|t|(|)| @60 +>++0#0000e05#a8a8a8255|-@1| |1@1| |l|i|n|e|s|:| |╚+0#0000001#ffd7ff255|═@3|⇲|-+0#0000e05#a8a8a8255@54 +|1+0#0000000#ffffff0@1| @72 +|++0#0000e05#a8a8a8255|-@1| |1@1| |l|i|n|e|s|:| |f|o|l|d| |-@55 +|2+0#0000000#ffffff0|3| @72 +|++0#0000e05#a8a8a8255|-@1| |1@1| |l|i|n|e|s|:| |f|o|l|d| |-@55 +|3+0#0000000#ffffff0|5| @72 +|++0#0000e05#a8a8a8255|-@1| |1@1| |l|i|n|e|s|:| |f|o|l|d| |-@55 +|4+0#0000000#ffffff0|7| @72 +|++0#0000e05#a8a8a8255|-@1| |1@1| |l|i|n|e|s|:| |f|o|l|d| |-@55 +|[+3#0000000#ffffff0|N|o| |N|a|m|e|]| |[|+|]| @61 +|:+0&&|c|a|l@1| |D|r|a|g|i|t|L|e|f|t|(|)| @56 diff --git a/src/testdir/dumps/Test_popupwin_term_03.dump b/src/testdir/dumps/Test_popupwin_term_03.dump new file mode 100644 --- /dev/null +++ b/src/testdir/dumps/Test_popupwin_term_03.dump @@ -0,0 +1,16 @@ +|v+0&#ffffff0|i|m|>| @70 +@75 +@75 +@75 +|!+0#ffffff16#00e0003|/|b|i|n|/|s|h| |[|r|u|n@1|i|n|g|]| @56 +>++0#0000e05#a8a8a8255|-@1| |1@1| |l|i|n|e|s|:| |f|o|l|d| |-@55 +|1+0#0000000#ffffff0@1| @72 +|++0#0000e05#a8a8a8255|-@1| |1@1| |l|i|n|e|s|:| |f|o|l|d| |-@55 +|2+0#0000000#ffffff0|3| @72 +|++0#0000e05#a8a8a8255|-@1| |1@1| |l|i|n|e|s|:| |f|o|l|d| |-@55 +|3+0#0000000#ffffff0|5| @72 +|++0#0000e05#a8a8a8255|-@1| |1@1| |l|i|n|e|s|:| |f|o|l|d| |-@14|╔+0#0000001#ffd7ff255|═@3|╗|-+0#0000e05#a8a8a8255@34 +|4+0#0000000#ffffff0|7| @31|║+0#0000001#ffd7ff255|1@3|║| +0#0000000#ffffff0@34 +|++0#0000e05#a8a8a8255|-@1| |1@1| |l|i|n|e|s|:| |f|o|l|d| |-@14|║+0#0000001#ffd7ff255|2@3|║|-+0#0000e05#a8a8a8255@34 +|[+3#0000000#ffffff0|N|o| |N|a|m|e|]| |[|+|]| @20|╚+0#0000001#ffd7ff255|═@3|⇲| +3#0000000#ffffff0@34 +|:+0&&|c|a|l@1| |D|r|a|g|i|t|D|o|w|n|(|)| @56 diff --git a/src/testdir/dumps/Test_popupwin_term_04.dump b/src/testdir/dumps/Test_popupwin_term_04.dump new file mode 100644 --- /dev/null +++ b/src/testdir/dumps/Test_popupwin_term_04.dump @@ -0,0 +1,16 @@ +|v+0&#ffffff0|i|m|>| @70 +@75 +@75 +@75 +|!+0#ffffff16#00e0003|/|b|i|n|/|s|h| |[|r|u|n@1|i|n|g|]| @56 +>++0#0000e05#a8a8a8255|-@1| |1@1| |l|i|n|e|s|:| |f|o|l|d| |-@55 +|1+0#0000000#ffffff0@1| @72 +|++0#0000e05#a8a8a8255|-@1| |1@1| |l|i|n|e|s|:| |f|o|l|d| |-@55 +|2+0#0000000#ffffff0|3| @72 +|++0#0000e05#a8a8a8255|-@1| |1@1| |l|i|n|e|s|:| |f|o|l|d| |-@55 +|3+0#0000000#ffffff0|5| @72 +|++0#0000e05#a8a8a8255|-@1| |1@1| |l|i|n|e|s|:| |╔+0#0000001#ffd7ff255|═@3|╗|-+0#0000e05#a8a8a8255@54 +|4+0#0000000#ffffff0|7| @11|║+0#0000001#ffd7ff255|1@3|║| +0#0000000#ffffff0@54 +|++0#0000e05#a8a8a8255|-@1| |1@1| |l|i|n|e|s|:| |║+0#0000001#ffd7ff255|2@3|║|-+0#0000e05#a8a8a8255@54 +|[+3#0000000#ffffff0|N|o| |N|a|m|e|]| |[|+|]| |╚+0#0000001#ffd7ff255|═@3|⇲| +3#0000000#ffffff0@54 +|:+0&&|c|a|l@1| |D|r|a|g|i|t|D|o|w|n|L|e|f|t|(|)| @52 diff --git a/src/testdir/test_popupwin.vim b/src/testdir/test_popupwin.vim --- a/src/testdir/test_popupwin.vim +++ b/src/testdir/test_popupwin.vim @@ -584,9 +584,16 @@ func Test_popup_drag_termwin() " create a popup that covers the terminal window let lines =<< trim END + set foldmethod=marker + call setline(1, range(100)) + for nr in range(7) + call setline(nr * 12 + 1, "fold {{{") + call setline(nr * 12 + 11 , "end }}}") + endfor + %foldclose set shell=/bin/sh noruler let $PS1 = 'vim> ' - terminal + terminal ++rows=4 $wincmd w let winid = popup_create(['1111', '2222'], #{ \ drag: 1, @@ -594,19 +601,33 @@ func Test_popup_drag_termwin() \ border: [], \ line: 3, \ }) - func Dragit() + func DragitLeft() call feedkeys("\\\\\", "xt") endfunc + func DragitDown() + call feedkeys("\\\\\", "xt") + endfunc + func DragitDownLeft() + call feedkeys("\\\\\", "xt") + endfunc map :call test_setmouse(3, &columns / 2) map :call test_setmouse(3, &columns / 2 - 20) + map :call test_setmouse(12, &columns / 2) + map :call test_setmouse(12, &columns / 2 - 20) END call writefile(lines, 'XtestPopupTerm') - let buf = RunVimInTerminal('-S XtestPopupTerm', #{rows: 10}) + let buf = RunVimInTerminal('-S XtestPopupTerm', #{rows: 16}) call VerifyScreenDump(buf, 'Test_popupwin_term_01', {}) - call term_sendkeys(buf, ":call Dragit()\") + call term_sendkeys(buf, ":call DragitLeft()\") call VerifyScreenDump(buf, 'Test_popupwin_term_02', {}) + call term_sendkeys(buf, ":call DragitDown()\") + call VerifyScreenDump(buf, 'Test_popupwin_term_03', {}) + + call term_sendkeys(buf, ":call DragitDownLeft()\") + call VerifyScreenDump(buf, 'Test_popupwin_term_04', {}) + " clean up call StopVimInTerminal(buf) call delete('XtestPopupTerm') diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -755,6 +755,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 1220, +/**/ 1219, /**/ 1218,