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

@@ -1073,6 +1073,7 @@ void * getline_cookie(LineGetter fgetline,
static int compute_buffer_local_count(int addr_type, int lnum, int offset)
{
buf_T *buf;
buf_T *nextbuf;
int count = offset;
buf = firstbuf;
@@ -1080,15 +1081,29 @@ static int compute_buffer_local_count(int addr_type, int lnum, int offset)
buf = buf->b_next;
while (count != 0) {
count += (count < 0) ? 1 : -1;
if (buf->b_prev == NULL)
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 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;
}
@@ -1404,7 +1419,7 @@ static char_u * do_one_cmd(char_u **cmdlinep,
* 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;
@@ -1441,15 +1456,25 @@ static char_u * do_one_cmd(char_u **cmdlinep,
goto doend;
if (lnum == MAXLNUM) {
if (*ea.cmd == '%') { /* '%' - all lines */
buf_T *buf;
++ea.cmd;
switch (ea.addr_type) {
case ADDR_LINES:
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_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;
@@ -3431,7 +3456,8 @@ static linenr_T get_address(char_u **ptr,
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
@@ -3451,18 +3477,16 @@ static linenr_T get_address(char_u **ptr,
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) {
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: