vim-patch:7.4.539

Patch 7.4.539 (after 7.4.530)
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)

https://code.google.com/p/vim/source/detail?name=v7-4-539
This commit is contained in:
Felipe Morales 2015-01-15 17:11:43 -03:00
parent f6c55022ff
commit c525085773
3 changed files with 49 additions and 19 deletions

View File

@ -283,7 +283,7 @@ CTRL-W CTRL-Q *CTRL-W_CTRL-Q*
:1quit " quit the first window :1quit " quit the first window
:$quit " quit the last window :$quit " quit the last window
:9quit " quit the last window :9quit " quit the last window
" if there are less than windows opened " if there are less than 9 windows opened
:-quit " quit the previous window :-quit " quit the previous window
:+quit " quit the next window :+quit " quit the next window
:+2quit " will also work as expected :+2quit " will also work as expected
@ -1027,8 +1027,11 @@ list of buffers. |unlisted-buffer|
Actually, the buffer isn't completely deleted, it is removed Actually, the buffer isn't completely deleted, it is removed
from the buffer list |unlisted-buffer| and option values, from the buffer list |unlisted-buffer| and option values,
variables and mappings/abbreviations for the buffer are 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* :bdelete[!] {bufname} *E93* *E94*
Like ":bdelete[!] [N]", but buffer given by name. Note that a Like ":bdelete[!] [N]", but buffer given by name. Note that a
buffer whose name is a number cannot be referenced by that buffer whose name is a number cannot be referenced by that
@ -1051,8 +1054,11 @@ list of buffers. |unlisted-buffer|
Like |:bdelete|, but really delete the buffer. Everything Like |:bdelete|, but really delete the buffer. Everything
related to the buffer is lost. All marks in this buffer related to the buffer is lost. All marks in this buffer
become invalid, option settings are lost, etc. Don't use this 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* :[N]bun[load][!] *:bun* *:bunload* *E515*
:bun[load][!] [N] :bun[load][!] [N]
Unload buffer [N] (default: current buffer). The memory Unload buffer [N] (default: current buffer). The memory

View File

@ -1073,6 +1073,7 @@ void * getline_cookie(LineGetter fgetline,
static int compute_buffer_local_count(int addr_type, int lnum, int offset) static int compute_buffer_local_count(int addr_type, int lnum, int offset)
{ {
buf_T *buf; buf_T *buf;
buf_T *nextbuf;
int count = offset; int count = offset;
buf = firstbuf; buf = firstbuf;
@ -1080,15 +1081,29 @@ static int compute_buffer_local_count(int addr_type, int lnum, int offset)
buf = buf->b_next; buf = buf->b_next;
while (count != 0) { while (count != 0) {
count += (count < 0) ? 1 : -1; count += (count < 0) ? 1 : -1;
if (buf->b_prev == NULL) nextbuf = (offset < 0) ? buf->b_prev : buf->b_next;
if (nextbuf == NULL)
break; break;
buf = (count < 0) ? buf->b_prev : buf->b_next; buf = nextbuf;
if (addr_type == ADDR_LOADED_BUFFERS) if (addr_type == ADDR_LOADED_BUFFERS)
/* skip over unloaded buffers */ /* skip over unloaded buffers */
while (buf->b_prev != NULL && buf->b_ml.ml_mfp == NULL) { while (buf->b_ml.ml_mfp == NULL) {
buf = (count < 0) ? buf->b_prev : buf->b_next; 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 loaded
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; return buf->b_fnum;
} }
@ -1404,7 +1419,7 @@ static char_u * do_one_cmd(char_u **cmdlinep,
* is equal to the lower. * 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; ea.addr_type = cmdnames[(int)ea.cmdidx].cmd_addr_type;
} else { } else {
ea.addr_type = ADDR_LINES; ea.addr_type = ADDR_LINES;
@ -1441,15 +1456,25 @@ static char_u * do_one_cmd(char_u **cmdlinep,
goto doend; goto doend;
if (lnum == MAXLNUM) { if (lnum == MAXLNUM) {
if (*ea.cmd == '%') { /* '%' - all lines */ if (*ea.cmd == '%') { /* '%' - all lines */
buf_T *buf;
++ea.cmd; ++ea.cmd;
switch (ea.addr_type) { switch (ea.addr_type) {
case ADDR_LINES: case ADDR_LINES:
ea.line1 = 1; ea.line1 = 1;
ea.line2 = curbuf->b_ml.ml_line_count; ea.line2 = curbuf->b_ml.ml_line_count;
break; break;
case ADDR_WINDOWS:
case ADDR_LOADED_BUFFERS: case ADDR_LOADED_BUFFERS:
buf = firstbuf;
while (buf->b_next != NULL && buf->b_ml.ml_mfp == NULL) {
buf = buf->b_prev;
}
ea.line2 = buf->b_fnum;
break;
case ADDR_UNLOADED_BUFFERS: case ADDR_UNLOADED_BUFFERS:
ea.line1 = firstbuf->b_fnum;
ea.line2 = lastbuf->b_fnum;
break;
case ADDR_WINDOWS:
case ADDR_TABS: case ADDR_TABS:
errormsg = (char_u *)_(e_invrange); errormsg = (char_u *)_(e_invrange);
goto doend; goto doend;
@ -3431,7 +3456,8 @@ static linenr_T get_address(char_u **ptr,
n = getdigits(&cmd); n = getdigits(&cmd);
if (addr_type == ADDR_LOADED_BUFFERS || if (addr_type == ADDR_LOADED_BUFFERS ||
addr_type == ADDR_UNLOADED_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 == '-') else if (i == '-')
lnum -= n; lnum -= n;
else else
@ -3451,18 +3477,16 @@ static linenr_T get_address(char_u **ptr,
lnum = 0; lnum = 0;
break; break;
} }
c = LAST_TAB_NR; if (lnum >= LAST_TAB_NR)
if (lnum >= c) lnum = LAST_TAB_NR;
lnum = c;
break; break;
case ADDR_WINDOWS: case ADDR_WINDOWS:
if (lnum < 0) { if (lnum < 0) {
lnum = 0; lnum = 0;
break; break;
} }
c = LAST_WIN_NR; if (lnum > LAST_WIN_NR)
if (lnum > c) lnum = LAST_WIN_NR;
lnum = c;
break; break;
case ADDR_LOADED_BUFFERS: case ADDR_LOADED_BUFFERS:
case ADDR_UNLOADED_BUFFERS: case ADDR_UNLOADED_BUFFERS:

View File

@ -240,7 +240,7 @@ static int included_patches[] = {
//542, //542,
541, 541,
//540 NA //540 NA
//539, 539,
538, 538,
537, 537,
536, 536,