diff options
author | Bram Moolenaar <Bram@vim.org> | 2014-11-30 14:50:16 +0100 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2014-11-30 14:50:16 +0100 |
commit | 4d84d9325f9537427f58c5ab0c1ce9a68be9d697 (patch) | |
tree | b54e4ba48b82f06f31543268123a28a098d2eda3 | |
parent | 0b105416066c95ade3604ec2139d8367d3c6e74e (diff) | |
download | vim-git-4d84d9325f9537427f58c5ab0c1ce9a68be9d697.tar.gz |
updated for version 7.4.539v7.4.539
Problem: Crash when computing buffer count. Problem with range for user
commands. Line range wrong in Visual area.
Solution: Avoid segfault in compute_buffer_local_count(). Check for
CMD_USER when checking type of range. (Marcin Szamotulski)
-rw-r--r-- | runtime/doc/windows.txt | 12 | ||||
-rw-r--r-- | src/ex_docmd.c | 55 | ||||
-rw-r--r-- | src/version.c | 2 |
3 files changed, 53 insertions, 16 deletions
diff --git a/runtime/doc/windows.txt b/runtime/doc/windows.txt index d116c9f6c..2830a04b8 100644 --- a/runtime/doc/windows.txt +++ b/runtime/doc/windows.txt @@ -1029,7 +1029,11 @@ list of buffers. |unlisted-buffer| Actually, the buffer isn't completely deleted, it is removed from the buffer list |unlisted-buffer| and option values, variables and mappings/abbreviations for the buffer are - cleared. + cleared. Examples: > + :.,$-bdelete " delete buffers from the current one to + " last but one + :%bdelete " delete all buffers +< :bdelete[!] {bufname} *E93* *E94* Like ":bdelete[!] [N]", but buffer given by name. Note that a @@ -1053,7 +1057,11 @@ list of buffers. |unlisted-buffer| Like |:bdelete|, but really delete the buffer. Everything related to the buffer is lost. All marks in this buffer become invalid, option settings are lost, etc. Don't use this - unless you know what you are doing. + unless you know what you are doing. Examples: > + :.+,$bwipeout " wipe out all buffers after the current + " one + :%bwipeout " wipe out all buffers +< :[N]bun[load][!] *:bun* *:bunload* *E515* :bun[load][!] [N] diff --git a/src/ex_docmd.c b/src/ex_docmd.c index 4ce9e926a..b926027f2 100644 --- a/src/ex_docmd.c +++ b/src/ex_docmd.c @@ -1694,6 +1694,7 @@ compute_buffer_local_count(addr_type, lnum, offset) int offset; { buf_T *buf; + buf_T *nextbuf; int count = offset; buf = firstbuf; @@ -1701,15 +1702,30 @@ compute_buffer_local_count(addr_type, lnum, offset) buf = buf->b_next; while (count != 0) { - count += (count < 0) ? 1 : -1; - if (buf->b_prev == NULL) + count += (offset < 0) ? 1 : -1; + nextbuf = (offset < 0) ? buf->b_prev : buf->b_next; + if (nextbuf == NULL) break; - buf = (count < 0) ? buf->b_prev : buf->b_next; + buf = nextbuf; if (addr_type == ADDR_LOADED_BUFFERS) /* skip over unloaded buffers */ - while (buf->b_prev != NULL && buf->b_ml.ml_mfp == NULL) - buf = (count < 0) ? buf->b_prev : buf->b_next; + while (buf->b_ml.ml_mfp == NULL) + { + nextbuf = (offset < 0) ? buf->b_prev : buf->b_next; + if (nextbuf == NULL) + break; + buf = nextbuf; + } } + /* we might have gone too far, last buffer is not loadedd */ + if (addr_type == ADDR_LOADED_BUFFERS) + while (buf->b_ml.ml_mfp == NULL) + { + nextbuf = (offset >= 0) ? buf->b_prev : buf->b_next; + if (nextbuf == NULL) + break; + buf = nextbuf; + } return buf->b_fnum; } @@ -2113,7 +2129,7 @@ do_one_cmd(cmdlinep, sourcing, * is equal to the lower. */ - if (ea.cmdidx != CMD_SIZE) + if (ea.cmdidx != CMD_USER && ea.cmdidx != CMD_SIZE) ea.addr_type = cmdnames[(int)ea.cmdidx].cmd_addr_type; else ea.addr_type = ADDR_LINES; @@ -2153,6 +2169,7 @@ do_one_cmd(cmdlinep, sourcing, { if (*ea.cmd == '%') /* '%' - all lines */ { + buf_T *buf; ++ea.cmd; switch (ea.addr_type) { @@ -2160,9 +2177,21 @@ do_one_cmd(cmdlinep, sourcing, ea.line1 = 1; ea.line2 = curbuf->b_ml.ml_line_count; break; - case ADDR_WINDOWS: case ADDR_LOADED_BUFFERS: + buf = firstbuf; + while (buf->b_next != NULL && buf->b_ml.ml_mfp == NULL) + buf = buf->b_next; + ea.line1 = buf->b_fnum; + buf = lastbuf; + while (buf->b_prev != NULL && buf->b_ml.ml_mfp == NULL) + buf = buf->b_prev; + ea.line2 = buf->b_fnum; + break; case ADDR_UNLOADED_BUFFERS: + ea.line1 = firstbuf->b_fnum; + ea.line2 = lastbuf->b_fnum; + break; + case ADDR_WINDOWS: case ADDR_TABS: errormsg = (char_u *)_(e_invrange); goto doend; @@ -4463,7 +4492,7 @@ get_address(ptr, addr_type, skip, to_other_file) n = getdigits(&cmd); if (addr_type == ADDR_LOADED_BUFFERS || addr_type == ADDR_UNLOADED_BUFFERS) - lnum = compute_buffer_local_count(addr_type, lnum, n); + lnum = compute_buffer_local_count(addr_type, lnum, (i == '-') ? -1 * n : n); else if (i == '-') lnum -= n; else @@ -4485,9 +4514,8 @@ get_address(ptr, addr_type, skip, to_other_file) lnum = 0; break; } - c = LAST_TAB_NR; - if (lnum >= c) - lnum = c; + if (lnum >= LAST_TAB_NR) + lnum = LAST_TAB_NR; break; case ADDR_WINDOWS: if (lnum < 0) @@ -4495,9 +4523,8 @@ get_address(ptr, addr_type, skip, to_other_file) lnum = 0; break; } - c = LAST_WIN_NR; - if (lnum > c) - lnum = c; + if (lnum >= LAST_WIN_NR) + lnum = LAST_WIN_NR; break; case ADDR_LOADED_BUFFERS: case ADDR_UNLOADED_BUFFERS: diff --git a/src/version.c b/src/version.c index 9545d0093..9e9e80281 100644 --- a/src/version.c +++ b/src/version.c @@ -742,6 +742,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 539, +/**/ 538, /**/ 537, |