Mercurial > vim
view src/testdir/mouse.vim @ 33815:08f9e1eac4cf v9.0.2123
patch 9.0.2123: Problem with initializing the length of range() lists
Commit: https://github.com/vim/vim/commit/df63da98d8dc284b1c76cfe1b17fa0acbd6094d8
Author: Christian Brabandt <cb@256bit.org>
Date: Thu Nov 23 20:14:28 2023 +0100
patch 9.0.2123: Problem with initializing the length of range() lists
Problem: Problem with initializing the length of range() lists
Solution: Set length explicitly when it shouldn't contain any items
range() may cause a wrong calculation of list length, which may later
then cause a segfault in list_find(). This is usually not a problem,
because range_list_materialize() calculates the length, when it
materializes the list.
In addition, in list_find() when the length of the range was wrongly
initialized, it may seem to be valid, so the check for list index
out-of-bounds will not be true, because it is called before the list is
actually materialized. And so we may eventually try to access a null
pointer, causing a segfault.
So this patch does 3 things:
- In f_range(), when we know that the list should be empty, explicitly
set the list->lv_len value to zero. This should happen, when
start is larger than end (in case the stride is positive) or
end is larger than start when the stride is negative.
This should fix the underlying issue properly. However,
- as a safety measure, let's check that the requested index is not
out of range one more time, after the list has been materialized
and return NULL in case it suddenly is.
- add a few more tests to verify the behaviour.
fixes: #13557
closes: #13563
Co-authored-by: Tim Pope <tpope@github.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
author | Christian Brabandt <cb@256bit.org> |
---|---|
date | Thu, 23 Nov 2023 20:30:07 +0100 |
parents | b9a4699d6a35 |
children |
line wrap: on
line source
" Helper functions for generating mouse events " xterm2 and sgr always work, urxvt is optional. let g:Ttymouse_values = ['xterm2', 'sgr'] if has('mouse_urxvt') call add(g:Ttymouse_values, 'urxvt') endif " dec doesn't support all the functionality if has('mouse_dec') let g:Ttymouse_dec = ['dec'] else let g:Ttymouse_dec = [] endif " netterm only supports left click if has('mouse_netterm') let g:Ttymouse_netterm = ['netterm'] else let g:Ttymouse_netterm = [] endif " Vim Mouse Codes. " Used by the GUI and by MS-Windows Consoles. " Keep these in sync with vim.h let s:MOUSE_CODE = { \ 'BTN_LEFT' : 0x00, \ 'BTN_MIDDLE' : 0x01, \ 'BTN_RIGHT' : 0x02, \ 'BTN_RELEASE' : 0x03, \ 'BTN_X1' : 0x300, \ 'BTN_X2' : 0x400, \ 'SCRL_DOWN' : 0x100, \ 'SCRL_UP' : 0x200, \ 'SCRL_LEFT' : 0x500, \ 'SCRL_RIGHT' : 0x600, \ 'MOVE' : 0x700, \ 'MOD_SHIFT' : 0x04, \ 'MOD_ALT' : 0x08, \ 'MOD_CTRL' : 0x10, \ } " Helper function to emit a terminal escape code. func TerminalEscapeCode(code, row, col, m) if &ttymouse ==# 'xterm2' " need to use byte encoding here. let str = list2str([a:code + 0x20, a:col + 0x20, a:row + 0x20]) if has('iconv') let bytes = str->iconv('utf-8', 'latin1') else " Hopefully the numbers are not too big. let bytes = str endif return "\<Esc>[M" .. bytes elseif &ttymouse ==# 'sgr' return printf("\<Esc>[<%d;%d;%d%s", a:code, a:col, a:row, a:m) elseif &ttymouse ==# 'urxvt' return printf("\<Esc>[%d;%d;%dM", a:code + 0x20, a:col, a:row) endif endfunc func DecEscapeCode(code, down, row, col) return printf("\<Esc>[%d;%d;%d;%d&w", a:code, a:down, a:row, a:col) endfunc func NettermEscapeCode(row, col) return printf("\<Esc>}%d,%d\r", a:row, a:col) endfunc " Send low level mouse event to MS-Windows consoles or GUI func MSWinMouseEvent(button, row, col, move, multiclick, modifiers) let args = { } let args.button = a:button " Scroll directions are inverted in the GUI, no idea why. if has('gui_running') if a:button == s:MOUSE_CODE.SCRL_UP let args.button = s:MOUSE_CODE.SCRL_DOWN elseif a:button == s:MOUSE_CODE.SCRL_DOWN let args.button = s:MOUSE_CODE.SCRL_UP elseif a:button == s:MOUSE_CODE.SCRL_LEFT let args.button = s:MOUSE_CODE.SCRL_RIGHT elseif a:button == s:MOUSE_CODE.SCRL_RIGHT let args.button = s:MOUSE_CODE.SCRL_LEFT endif endif let args.row = a:row let args.col = a:col let args.move = a:move let args.multiclick = a:multiclick let args.modifiers = a:modifiers call test_mswin_event("mouse", args) unlet args endfunc func MouseLeftClickCode(row, col) if &ttymouse ==# 'dec' return DecEscapeCode(2, 4, a:row, a:col) elseif &ttymouse ==# 'netterm' return NettermEscapeCode(a:row, a:col) else return TerminalEscapeCode(0, a:row, a:col, 'M') endif endfunc func MouseLeftClick(row, col) if has('win32') call MSWinMouseEvent(s:MOUSE_CODE.BTN_LEFT, a:row, a:col, 0, 0, 0) else call feedkeys(MouseLeftClickCode(a:row, a:col), 'Lx!') endif endfunc func MouseMiddleClickCode(row, col) if &ttymouse ==# 'dec' return DecEscapeCode(4, 2, a:row, a:col) else return TerminalEscapeCode(1, a:row, a:col, 'M') endif endfunc func MouseMiddleClick(row, col) if has('win32') call MSWinMouseEvent(s:MOUSE_CODE.BTN_MIDDLE, a:row, a:col, 0, 0, 0) else call feedkeys(MouseMiddleClickCode(a:row, a:col), 'Lx!') endif endfunc func MouseRightClickCode(row, col) if &ttymouse ==# 'dec' return DecEscapeCode(6, 1, a:row, a:col) else return TerminalEscapeCode(2, a:row, a:col, 'M') endif endfunc func MouseRightClick(row, col) if has('win32') call MSWinMouseEvent(s:MOUSE_CODE.BTN_RIGHT, a:row, a:col, 0, 0, 0) else call feedkeys(MouseRightClickCode(a:row, a:col), 'Lx!') endif endfunc func MouseCtrlLeftClickCode(row, col) let ctrl = 0x10 return TerminalEscapeCode(0 + ctrl, a:row, a:col, 'M') endfunc func MouseCtrlLeftClick(row, col) if has('win32') call MSWinMouseEvent(s:MOUSE_CODE.BTN_LEFT, a:row, a:col, 0, 0, \ s:MOUSE_CODE.MOD_CTRL) else call feedkeys(MouseCtrlLeftClickCode(a:row, a:col), 'Lx!') endif endfunc func MouseCtrlRightClickCode(row, col) let ctrl = 0x10 return TerminalEscapeCode(2 + ctrl, a:row, a:col, 'M') endfunc func MouseCtrlRightClick(row, col) if has('win32') call MSWinMouseEvent(s:MOUSE_CODE.BTN_RIGHT, a:row, a:col, 0, 0, \ s:MOUSE_CODE.MOD_CTRL) else call feedkeys(MouseCtrlRightClickCode(a:row, a:col), 'Lx!') endif endfunc func MouseAltLeftClickCode(row, col) let alt = 0x8 return TerminalEscapeCode(0 + alt, a:row, a:col, 'M') endfunc func MouseAltLeftClick(row, col) if has('win32') call MSWinMouseEvent(s:MOUSE_CODE.BTN_LEFT, a:row, a:col, 0, 0, \ s:MOUSE_CODE.MOD_ALT) else call feedkeys(MouseAltLeftClickCode(a:row, a:col), 'Lx!') endif endfunc func MouseAltRightClickCode(row, col) let alt = 0x8 return TerminalEscapeCode(2 + alt, a:row, a:col, 'M') endfunc func MouseAltRightClick(row, col) if has('win32') call MSWinMouseEvent(s:MOUSE_CODE.BTN_RIGHT, a:row, a:col, 0, 0, \ s:MOUSE_CODE.MOD_ALT) else call feedkeys(MouseAltRightClickCode(a:row, a:col), 'Lx!') endif endfunc func MouseLeftReleaseCode(row, col) if &ttymouse ==# 'dec' return DecEscapeCode(3, 0, a:row, a:col) elseif &ttymouse ==# 'netterm' return '' else return TerminalEscapeCode(3, a:row, a:col, 'm') endif endfunc func MouseLeftRelease(row, col) if has('win32') call MSWinMouseEvent(s:MOUSE_CODE.BTN_RELEASE, a:row, a:col, 0, 0, 0) else call feedkeys(MouseLeftReleaseCode(a:row, a:col), 'Lx!') endif endfunc func MouseMiddleReleaseCode(row, col) if &ttymouse ==# 'dec' return DecEscapeCode(5, 0, a:row, a:col) else return TerminalEscapeCode(3, a:row, a:col, 'm') endif endfunc func MouseMiddleRelease(row, col) if has('win32') call MSWinMouseEvent(s:MOUSE_CODE.BTN_RELEASE, a:row, a:col, 0, 0, 0) else call feedkeys(MouseMiddleReleaseCode(a:row, a:col), 'Lx!') endif endfunc func MouseRightReleaseCode(row, col) if &ttymouse ==# 'dec' return DecEscapeCode(7, 0, a:row, a:col) else return TerminalEscapeCode(3, a:row, a:col, 'm') endif endfunc func MouseRightRelease(row, col) if has('win32') call MSWinMouseEvent(s:MOUSE_CODE.BTN_RELEASE, a:row, a:col, 0, 0, 0) else call feedkeys(MouseRightReleaseCode(a:row, a:col), 'Lx!') endif endfunc func MouseLeftDragCode(row, col) if &ttymouse ==# 'dec' return DecEscapeCode(1, 4, a:row, a:col) else return TerminalEscapeCode(0x20, a:row, a:col, 'M') endif endfunc func MouseLeftDrag(row, col) if has('win32') call MSWinMouseEvent(s:MOUSE_CODE.BTN_LEFT, a:row, a:col, 1, 0, 0) else call feedkeys(MouseLeftDragCode(a:row, a:col), 'Lx!') endif endfunc func MouseWheelUpCode(row, col) return TerminalEscapeCode(0x40, a:row, a:col, 'M') endfunc func MouseWheelUp(row, col) if has('win32') call MSWinMouseEvent(s:MOUSE_CODE.SCRL_UP, a:row, a:col, 0, 0, 0) else call feedkeys(MouseWheelUpCode(a:row, a:col), 'Lx!') endif endfunc func MouseWheelDownCode(row, col) return TerminalEscapeCode(0x41, a:row, a:col, 'M') endfunc func MouseWheelDown(row, col) if has('win32') call MSWinMouseEvent(s:MOUSE_CODE.SCRL_DOWN, a:row, a:col, 0, 0, 0) else call feedkeys(MouseWheelDownCode(a:row, a:col), 'Lx!') endif endfunc func MouseWheelLeftCode(row, col) return TerminalEscapeCode(0x42, a:row, a:col, 'M') endfunc func MouseWheelLeft(row, col) if has('win32') call MSWinMouseEvent(s:MOUSE_CODE.SCRL_LEFT, a:row, a:col, 0, 0, 0) else call feedkeys(MouseWheelLeftCode(a:row, a:col), 'Lx!') endif endfunc func MouseWheelRightCode(row, col) return TerminalEscapeCode(0x43, a:row, a:col, 'M') endfunc func MouseWheelRight(row, col) if has('win32') call MSWinMouseEvent(s:MOUSE_CODE.SCRL_RIGHT, a:row, a:col, 0, 0, 0) else call feedkeys(MouseWheelRightCode(a:row, a:col), 'Lx!') endif endfunc func MouseShiftWheelUpCode(row, col) " todo feed shift mod. return TerminalEscapeCode(0x40, a:row, a:col, 'M') endfunc func MouseShiftWheelUp(row, col) if has('win32') call MSWinMouseEvent(s:MOUSE_CODE.SCRL_UP, a:row, a:col, 0, 0, \ s:MOUSE_CODE.MOD_SHIFT) else call feedkeys(MouseShiftWheelUpCode(a:row, a:col), 'Lx!') endif endfunc func MouseShiftWheelDownCode(row, col) " todo feed shift mod. return TerminalEscapeCode(0x41, a:row, a:col, 'M') endfunc func MouseShiftWheelDown(row, col) if has('win32') call MSWinMouseEvent(s:MOUSE_CODE.SCRL_DOWN, a:row, a:col, 0, 0, \ s:MOUSE_CODE.MOD_SHIFT) else call feedkeys(MouseShiftWheelDownCode(a:row, a:col), 'Lx!') endif endfunc func MouseShiftWheelLeftCode(row, col) " todo feed shift mod. return TerminalEscapeCode(0x42, a:row, a:col, 'M') endfunc func MouseShiftWheelLeft(row, col) if has('win32') call MSWinMouseEvent(s:MOUSE_CODE.SCRL_LEFT, a:row, a:col, 0, 0, \ s:MOUSE_CODE.MOD_SHIFT) else call feedkeys(MouseShiftWheelLeftCode(a:row, a:col), 'Lx!') endif endfunc func MouseShiftWheelRightCode(row, col) " todo feed shift mod. return TerminalEscapeCode(0x43, a:row, a:col, 'M') endfunc func MouseShiftWheelRight(row, col) if has('win32') call MSWinMouseEvent(s:MOUSE_CODE.SCRL_RIGHT, a:row, a:col, 0, 0, \ s:MOUSE_CODE.MOD_SHIFT) else call feedkeys(MouseShiftWheelRightCode(a:row, a:col), 'Lx!') endif endfunc " vim: shiftwidth=2 sts=2 expandtab