mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
vim-patch:7.4.565
Problem: Ranges for arguments, buffers, tabs, etc. are not checked to be valid but limited to the maximum. This can cause the wrong thing to happen. Solution: Give an error for an invalid value. (Marcin Szamotulski) Use windows range for ":wincmd". https://code.google.com/p/vim/source/detail?r=v7-4-565
This commit is contained in:
parent
d2ad709a1e
commit
ca883df007
@ -2992,7 +2992,7 @@ return {
|
||||
{
|
||||
command='wincmd',
|
||||
flags=bit.bor(NEEDARG, WORD1, RANGE, NOTADR),
|
||||
addr_type=ADDR_LINES,
|
||||
addr_type=ADDR_WINDOWS,
|
||||
func='ex_wincmd',
|
||||
},
|
||||
{
|
||||
|
@ -1446,6 +1446,9 @@ static char_u * do_one_cmd(char_u **cmdlinep,
|
||||
break;
|
||||
case ADDR_ARGUMENTS:
|
||||
ea.line2 = curwin->w_arg_idx + 1;
|
||||
if (ea.line2 > ARGCOUNT) {
|
||||
ea.line2 = ARGCOUNT;
|
||||
}
|
||||
break;
|
||||
case ADDR_LOADED_BUFFERS:
|
||||
case ADDR_BUFFERS:
|
||||
@ -2247,7 +2250,7 @@ static char_u *find_command(exarg_T *eap, int *full)
|
||||
* Exceptions:
|
||||
* - the 'k' command can directly be followed by any character.
|
||||
* - the 's' command can be followed directly by 'c', 'g', 'i', 'I' or 'r'
|
||||
* but :sre[wind] is another command, as are :scrip[tnames],
|
||||
* but :sre[wind] is another command, as are :scr[iptnames],
|
||||
* :scs[cope], :sim[alt], :sig[ns] and :sil[ent].
|
||||
* - the "d" command can directly be followed by 'l' or 'p' flag.
|
||||
*/
|
||||
@ -3517,40 +3520,6 @@ static linenr_T get_address(char_u **ptr,
|
||||
lnum -= n;
|
||||
else
|
||||
lnum += n;
|
||||
|
||||
switch (addr_type) {
|
||||
case ADDR_LINES:
|
||||
break;
|
||||
case ADDR_ARGUMENTS:
|
||||
if (lnum < 0)
|
||||
lnum = 0;
|
||||
else if (lnum >= ARGCOUNT)
|
||||
lnum = ARGCOUNT;
|
||||
break;
|
||||
case ADDR_TABS:
|
||||
if (lnum < 0) {
|
||||
lnum = 0;
|
||||
break;
|
||||
}
|
||||
if (lnum >= LAST_TAB_NR)
|
||||
lnum = LAST_TAB_NR;
|
||||
break;
|
||||
case ADDR_WINDOWS:
|
||||
if (lnum < 0) {
|
||||
lnum = 0;
|
||||
break;
|
||||
}
|
||||
if (lnum > LAST_WIN_NR)
|
||||
lnum = LAST_WIN_NR;
|
||||
break;
|
||||
case ADDR_LOADED_BUFFERS:
|
||||
case ADDR_BUFFERS:
|
||||
if (lnum < firstbuf->b_fnum) {
|
||||
lnum = firstbuf->b_fnum;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
} while (*cmd == '/' || *cmd == '?');
|
||||
|
||||
@ -3599,15 +3568,65 @@ static void ex_script_ni(exarg_T *eap)
|
||||
*/
|
||||
static char_u *invalid_range(exarg_T *eap)
|
||||
{
|
||||
if ( eap->line1 < 0
|
||||
|| eap->line2 < 0
|
||||
|| eap->line1 > eap->line2
|
||||
|| ((eap->argt & RANGE)
|
||||
&& !(eap->argt & NOTADR)
|
||||
&& eap->line2 > curbuf->b_ml.ml_line_count
|
||||
+ (eap->cmdidx == CMD_diffget)
|
||||
))
|
||||
buf_T *buf;
|
||||
if (eap->line1 < 0 || eap->line2 < 0 || eap->line1 > eap->line2) {
|
||||
return (char_u *)_(e_invrange);
|
||||
}
|
||||
|
||||
if (eap->argt & RANGE) {
|
||||
switch (eap->addr_type) {
|
||||
case ADDR_LINES:
|
||||
if (!(eap->argt & NOTADR) &&
|
||||
eap->line2 >
|
||||
curbuf->b_ml.ml_line_count + (eap->cmdidx == CMD_diffget)) {
|
||||
return (char_u *)_(e_invrange);
|
||||
}
|
||||
break;
|
||||
case ADDR_ARGUMENTS:
|
||||
if (eap->line2 > ARGCOUNT + (!ARGCOUNT)) { // add 1 if ARGCOUNT is 0
|
||||
return (char_u *)_(e_invrange);
|
||||
}
|
||||
break;
|
||||
case ADDR_BUFFERS:
|
||||
if (eap->line1 < firstbuf->b_fnum || eap->line2 > lastbuf->b_fnum) {
|
||||
return (char_u *)_(e_invrange);
|
||||
}
|
||||
break;
|
||||
case ADDR_LOADED_BUFFERS:
|
||||
buf = firstbuf;
|
||||
while (buf->b_ml.ml_mfp == NULL) {
|
||||
if (buf->b_next == NULL) {
|
||||
return (char_u *)_(e_invrange);
|
||||
}
|
||||
buf = buf->b_next;
|
||||
}
|
||||
if (eap->line1 < buf->b_fnum) {
|
||||
return (char_u *)_(e_invrange);
|
||||
}
|
||||
buf = lastbuf;
|
||||
while (buf->b_ml.ml_mfp == NULL) {
|
||||
if (buf->b_prev == NULL) {
|
||||
return (char_u *)_(e_invrange);
|
||||
}
|
||||
buf = buf->b_prev;
|
||||
}
|
||||
if (eap->line2 > buf->b_fnum) {
|
||||
return (char_u *)_(e_invrange);
|
||||
}
|
||||
break;
|
||||
case ADDR_WINDOWS:
|
||||
if (eap->line1 < 1
|
||||
|| eap->line2 > LAST_WIN_NR) {
|
||||
return (char_u *)_(e_invrange);
|
||||
}
|
||||
break;
|
||||
case ADDR_TABS:
|
||||
if (eap->line2 > LAST_TAB_NR) {
|
||||
return (char_u *)_(e_invrange);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -13,7 +13,7 @@ STARTTEST
|
||||
:" Open three tab pages and use ":tabdo"
|
||||
:0tabnew
|
||||
:1tabnew
|
||||
:888tabnew
|
||||
:$tabnew
|
||||
:tabdo call append(line('$'), 'this is tab page ' . tabpagenr())
|
||||
:tabclose! 2
|
||||
:tabrewind
|
||||
|
@ -26,10 +26,9 @@ STARTTEST
|
||||
:1arga c
|
||||
:1arga b
|
||||
:$argu
|
||||
:+arga d
|
||||
:$arga x
|
||||
:call add(arglists, argv())
|
||||
:$-10arga Y
|
||||
:0arga Y
|
||||
:call add(arglists, argv())
|
||||
:%argd
|
||||
:call add(arglists, argv())
|
||||
|
@ -7,7 +7,7 @@ c
|
||||
a b d
|
||||
a d
|
||||
a
|
||||
a b c d x
|
||||
Y a b c d x
|
||||
a b c x
|
||||
Y a b c x
|
||||
|
||||
a f
|
||||
|
@ -28,7 +28,7 @@ STARTTEST
|
||||
:new
|
||||
:new
|
||||
:2wincmd w
|
||||
:-2close!
|
||||
:-1close!
|
||||
:let buffers = []
|
||||
:windo call add(buffers, bufnr('%'))
|
||||
:call add(tests, buffers)
|
||||
@ -62,7 +62,7 @@ STARTTEST
|
||||
:let buffers = []
|
||||
:windo call add(buffers, bufnr('%'))
|
||||
:call add(tests, buffers)
|
||||
:9hide
|
||||
:$hide
|
||||
:let buffers = []
|
||||
:windo call add(buffers, bufnr('%'))
|
||||
:call add(tests, buffers)
|
||||
|
@ -1,8 +1,8 @@
|
||||
Test for user command counts vim: set ft=vim :
|
||||
|
||||
STARTTEST
|
||||
:let g:lines = []
|
||||
:so tiny.vim
|
||||
:let g:lines = []
|
||||
:com -range=% RangeLines :call add(g:lines, 'RangeLines '.<line1>.' '.<line2>)
|
||||
:com -range -addr=arguments RangeArguments :call add(g:lines, 'RangeArguments '.<line1>.' '.<line2>)
|
||||
:com -range=% -addr=arguments RangeArgumentsAll :call add(g:lines, 'RangeArgumentsAll '.<line1>.' '.<line2>)
|
||||
@ -48,6 +48,46 @@ STARTTEST
|
||||
:'<,'>RangeLines
|
||||
:com -range=% -buffer LocalRangeLines :call add(g:lines, 'LocalRangeLines '.<line1>.' '.<line2>)
|
||||
:'<,'>LocalRangeLines
|
||||
:b1
|
||||
ENDTEST
|
||||
|
||||
STARTTEST
|
||||
:call add(g:lines, '')
|
||||
:%argd
|
||||
:arga a b c d
|
||||
:let v:errmsg = ''
|
||||
:5argu
|
||||
:call add(g:lines, '5argu ' . v:errmsg)
|
||||
:$argu
|
||||
:call add(g:lines, '4argu ' . expand('%:t'))
|
||||
:let v:errmsg = ''
|
||||
:1argu
|
||||
:call add(g:lines, '1argu ' . expand('%:t'))
|
||||
:let v:errmsg = ''
|
||||
:100b
|
||||
:call add(g:lines, '100b ' . v:errmsg)
|
||||
:split|split|split|split
|
||||
:let v:errmsg = ''
|
||||
:0close
|
||||
:call add(g:lines, '0close ' . v:errmsg)
|
||||
:$wincmd w
|
||||
:$close
|
||||
:call add(g:lines, '$close ' . winnr())
|
||||
:let v:errmsg = ''
|
||||
:$+close
|
||||
:call add(g:lines, '$+close ' . v:errmsg)
|
||||
:$tabe
|
||||
:call add(g:lines, '$tabe ' . tabpagenr())
|
||||
:let v:errmsg = ''
|
||||
:$+tabe
|
||||
:call add(g:lines, '$+tabe ' . v:errmsg)
|
||||
:only!
|
||||
:e x
|
||||
:0tabm
|
||||
:normal 1gt
|
||||
:call add(g:lines, '0tabm ' . expand('%:t'))
|
||||
:tabonly!
|
||||
:only!
|
||||
:e! test.out
|
||||
:call append(0, g:lines)
|
||||
:w|qa!
|
||||
|
@ -17,3 +17,14 @@ RangeTabsAll 1 5
|
||||
RangeLines 2 5
|
||||
LocalRangeLines 2 5
|
||||
|
||||
5argu E16: Invalid range
|
||||
4argu d
|
||||
1argu a
|
||||
100b E16: Invalid range
|
||||
0close E16: Invalid range
|
||||
$close 4
|
||||
$+close E16: Invalid range
|
||||
$tabe 2
|
||||
$+tabe E16: Invalid range
|
||||
0tabm x
|
||||
|
||||
|
@ -214,7 +214,7 @@ static int included_patches[] = {
|
||||
//568,
|
||||
567,
|
||||
//566,
|
||||
//565,
|
||||
565,
|
||||
//564,
|
||||
563,
|
||||
//562,
|
||||
|
Loading…
Reference in New Issue
Block a user