diff options
author | Bram Moolenaar <Bram@vim.org> | 2015-01-07 15:57:17 +0100 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2015-01-07 15:57:17 +0100 |
commit | 3ffc79a4a82918430940bfaa18f4da058fdbd0ca (patch) | |
tree | 23f835e3a04e947649932304913b06ddb6c09cae /src/ex_docmd.c | |
parent | 49a6ed8a8a5fa471bf99f8d068e7cb994c2af163 (diff) |
updated for version 7.4.565v7.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".
Diffstat (limited to 'src/ex_docmd.c')
-rw-r--r-- | src/ex_docmd.c | 106 |
1 files changed, 58 insertions, 48 deletions
diff --git a/src/ex_docmd.c b/src/ex_docmd.c index b37c6ed8cc..3276abfdbc 100644 --- a/src/ex_docmd.c +++ b/src/ex_docmd.c @@ -2161,6 +2161,8 @@ do_one_cmd(cmdlinep, sourcing, 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: @@ -3110,7 +3112,7 @@ find_command(eap, 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. */ @@ -4573,46 +4575,6 @@ get_address(ptr, addr_type, skip, to_other_file) 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; - } - if (lnum > lastbuf->b_fnum) - lnum = lastbuf->b_fnum; - break; - } } } while (*cmd == '/' || *cmd == '?'); @@ -4675,17 +4637,65 @@ ex_script_ni(eap) invalid_range(eap) exarg_T *eap; { + buf_T *buf; 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->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 #ifdef FEAT_DIFF - + (eap->cmdidx == CMD_diffget) + + (eap->cmdidx == CMD_diffget) #endif - )) - return (char_u *)_(e_invrange); + ) + return (char_u *)_(e_invrange); + break; + case ADDR_ARGUMENTS: + if (eap->line2 > ARGCOUNT + (!ARGCOUNT)) // add 1 if ARCOUNT 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; } |