forked from aniani/vim
patch 8.0.0607: after :bwipe + :new bufref might still be valid
Problem: When creating a bufref, then using :bwipe and :new it might get the same memory and bufref_valid() returns true. Solution: Add br_fnum to check the buffer number didn't change.
This commit is contained in:
19
src/buffer.c
19
src/buffer.c
@@ -372,18 +372,23 @@ open_buffer(
|
|||||||
set_bufref(bufref_T *bufref, buf_T *buf)
|
set_bufref(bufref_T *bufref, buf_T *buf)
|
||||||
{
|
{
|
||||||
bufref->br_buf = buf;
|
bufref->br_buf = buf;
|
||||||
|
bufref->br_fnum = buf->b_fnum;
|
||||||
bufref->br_buf_free_count = buf_free_count;
|
bufref->br_buf_free_count = buf_free_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Return TRUE if "bufref->br_buf" points to a valid buffer.
|
* Return TRUE if "bufref->br_buf" points to the same buffer as when
|
||||||
|
* set_bufref() was called and it is a valid buffer.
|
||||||
* Only goes through the buffer list if buf_free_count changed.
|
* Only goes through the buffer list if buf_free_count changed.
|
||||||
|
* Also checks if b_fnum is still the same, a :bwipe followed by :new might get
|
||||||
|
* the same allocated memory, but it's a different buffer.
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
bufref_valid(bufref_T *bufref)
|
bufref_valid(bufref_T *bufref)
|
||||||
{
|
{
|
||||||
return bufref->br_buf_free_count == buf_free_count
|
return bufref->br_buf_free_count == buf_free_count
|
||||||
? TRUE : buf_valid(bufref->br_buf);
|
? TRUE : buf_valid(bufref->br_buf)
|
||||||
|
&& bufref->br_fnum == bufref->br_buf->b_fnum;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -2261,14 +2266,14 @@ free_buf_options(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* get alternate file n
|
* Get alternate file "n".
|
||||||
* set linenr to lnum or altfpos.lnum if lnum == 0
|
* Set linenr to "lnum" or altfpos.lnum if "lnum" == 0.
|
||||||
* also set cursor column to altfpos.col if 'startofline' is not set.
|
* Also set cursor column to altfpos.col if 'startofline' is not set.
|
||||||
* if (options & GETF_SETMARK) call setpcmark()
|
* if (options & GETF_SETMARK) call setpcmark()
|
||||||
* if (options & GETF_ALT) we are jumping to an alternate file.
|
* if (options & GETF_ALT) we are jumping to an alternate file.
|
||||||
* if (options & GETF_SWITCH) respect 'switchbuf' settings when jumping
|
* if (options & GETF_SWITCH) respect 'switchbuf' settings when jumping
|
||||||
*
|
*
|
||||||
* return FAIL for failure, OK for success
|
* Return FAIL for failure, OK for success.
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
buflist_getfile(
|
buflist_getfile(
|
||||||
@@ -2999,7 +3004,7 @@ buflist_findlnum(buf_T *buf)
|
|||||||
|
|
||||||
#if defined(FEAT_LISTCMDS) || defined(PROTO)
|
#if defined(FEAT_LISTCMDS) || defined(PROTO)
|
||||||
/*
|
/*
|
||||||
* List all know file names (for :files and :buffers command).
|
* List all known file names (for :files and :buffers command).
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
buflist_list(exarg_T *eap)
|
buflist_list(exarg_T *eap)
|
||||||
|
@@ -385,7 +385,7 @@ EXTERN int keep_filetype INIT(= FALSE); /* value for did_filetype when
|
|||||||
|
|
||||||
/* When deleting the current buffer, another one must be loaded. If we know
|
/* When deleting the current buffer, another one must be loaded. If we know
|
||||||
* which one is preferred, au_new_curbuf is set to it */
|
* which one is preferred, au_new_curbuf is set to it */
|
||||||
EXTERN bufref_T au_new_curbuf INIT(= {NULL COMMA 0});
|
EXTERN bufref_T au_new_curbuf INIT(= {NULL COMMA 0 COMMA 0});
|
||||||
|
|
||||||
/* When deleting a buffer/window and autocmd_busy is TRUE, do not free the
|
/* When deleting a buffer/window and autocmd_busy is TRUE, do not free the
|
||||||
* buffer/window. but link it in the list starting with
|
* buffer/window. but link it in the list starting with
|
||||||
|
@@ -4311,7 +4311,7 @@ restore_win_for_buf(
|
|||||||
static int
|
static int
|
||||||
SetBufferLine(buf_T *buf, PyInt n, PyObject *line, PyInt *len_change)
|
SetBufferLine(buf_T *buf, PyInt n, PyObject *line, PyInt *len_change)
|
||||||
{
|
{
|
||||||
bufref_T save_curbuf = {NULL, 0};
|
bufref_T save_curbuf = {NULL, 0, 0};
|
||||||
win_T *save_curwin = NULL;
|
win_T *save_curwin = NULL;
|
||||||
tabpage_T *save_curtab = NULL;
|
tabpage_T *save_curtab = NULL;
|
||||||
|
|
||||||
@@ -4415,7 +4415,7 @@ SetBufferLineList(
|
|||||||
PyObject *list,
|
PyObject *list,
|
||||||
PyInt *len_change)
|
PyInt *len_change)
|
||||||
{
|
{
|
||||||
bufref_T save_curbuf = {NULL, 0};
|
bufref_T save_curbuf = {NULL, 0, 0};
|
||||||
win_T *save_curwin = NULL;
|
win_T *save_curwin = NULL;
|
||||||
tabpage_T *save_curtab = NULL;
|
tabpage_T *save_curtab = NULL;
|
||||||
|
|
||||||
@@ -4616,7 +4616,7 @@ SetBufferLineList(
|
|||||||
static int
|
static int
|
||||||
InsertBufferLines(buf_T *buf, PyInt n, PyObject *lines, PyInt *len_change)
|
InsertBufferLines(buf_T *buf, PyInt n, PyObject *lines, PyInt *len_change)
|
||||||
{
|
{
|
||||||
bufref_T save_curbuf = {NULL, 0};
|
bufref_T save_curbuf = {NULL, 0, 0};
|
||||||
win_T *save_curwin = NULL;
|
win_T *save_curwin = NULL;
|
||||||
tabpage_T *save_curtab = NULL;
|
tabpage_T *save_curtab = NULL;
|
||||||
|
|
||||||
|
@@ -161,8 +161,8 @@ static qf_info_T *ll_get_or_alloc_list(win_T *);
|
|||||||
* Looking up a buffer can be slow if there are many. Remember the last one
|
* Looking up a buffer can be slow if there are many. Remember the last one
|
||||||
* to make this a lot faster if there are multiple matches in the same file.
|
* to make this a lot faster if there are multiple matches in the same file.
|
||||||
*/
|
*/
|
||||||
static char_u *qf_last_bufname = NULL;
|
static char_u *qf_last_bufname = NULL;
|
||||||
static bufref_T qf_last_bufref = {NULL, 0};
|
static bufref_T qf_last_bufref = {NULL, 0, 0};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Read the errorfile "efile" into memory, line by line, building the error
|
* Read the errorfile "efile" into memory, line by line, building the error
|
||||||
@@ -2732,7 +2732,7 @@ qf_history(exarg_T *eap)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Free error list "idx".
|
* Free all the entries in the error list "idx".
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
qf_free(qf_info_T *qi, int idx)
|
qf_free(qf_info_T *qi, int idx)
|
||||||
|
@@ -69,11 +69,13 @@ typedef struct frame_S frame_T;
|
|||||||
typedef int scid_T; /* script ID */
|
typedef int scid_T; /* script ID */
|
||||||
typedef struct file_buffer buf_T; /* forward declaration */
|
typedef struct file_buffer buf_T; /* forward declaration */
|
||||||
|
|
||||||
/* Reference to a buffer that stores the value of buf_free_count.
|
/*
|
||||||
|
* Reference to a buffer that stores the value of buf_free_count.
|
||||||
* bufref_valid() only needs to check "buf" when the count differs.
|
* bufref_valid() only needs to check "buf" when the count differs.
|
||||||
*/
|
*/
|
||||||
typedef struct {
|
typedef struct {
|
||||||
buf_T *br_buf;
|
buf_T *br_buf;
|
||||||
|
int br_fnum;
|
||||||
int br_buf_free_count;
|
int br_buf_free_count;
|
||||||
} bufref_T;
|
} bufref_T;
|
||||||
|
|
||||||
|
@@ -764,6 +764,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
607,
|
||||||
/**/
|
/**/
|
||||||
606,
|
606,
|
||||||
/**/
|
/**/
|
||||||
|
Reference in New Issue
Block a user