mirror of
https://github.com/neovim/neovim.git
synced 2025-09-08 12:28:18 +00:00
vim-patch:8.0.0607 (#6879)
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.
45e5fd135d
This commit is contained in:

committed by
Justin M. Keyes

parent
90f20bd7b1
commit
d0ff2000b2
@@ -330,7 +330,7 @@ void nvim_buf_set_lines(uint64_t channel_id,
|
|||||||
}
|
}
|
||||||
|
|
||||||
try_start();
|
try_start();
|
||||||
bufref_T save_curbuf = { NULL, 0 };
|
bufref_T save_curbuf = { NULL, 0, 0 };
|
||||||
switch_to_win_for_buf(buf, &save_curwin, &save_curtab, &save_curbuf);
|
switch_to_win_for_buf(buf, &save_curwin, &save_curtab, &save_curbuf);
|
||||||
|
|
||||||
if (u_save((linenr_T)(start - 1), (linenr_T)end) == FAIL) {
|
if (u_save((linenr_T)(start - 1), (linenr_T)end) == FAIL) {
|
||||||
|
@@ -961,7 +961,7 @@ static void set_option_value_for(char *key,
|
|||||||
{
|
{
|
||||||
win_T *save_curwin = NULL;
|
win_T *save_curwin = NULL;
|
||||||
tabpage_T *save_curtab = NULL;
|
tabpage_T *save_curtab = NULL;
|
||||||
bufref_T save_curbuf = { NULL, 0 };
|
bufref_T save_curbuf = { NULL, 0, 0 };
|
||||||
|
|
||||||
try_start();
|
try_start();
|
||||||
switch (opt_type)
|
switch (opt_type)
|
||||||
|
@@ -281,19 +281,22 @@ open_buffer (
|
|||||||
void set_bufref(bufref_T *bufref, buf_T *buf)
|
void 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Check if "bufref" 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.
|
||||||
///
|
///
|
||||||
/// @param bufref Buffer reference to check for.
|
/// @param bufref Buffer reference to check for.
|
||||||
bool bufref_valid(bufref_T *bufref)
|
bool bufref_valid(bufref_T *bufref)
|
||||||
{
|
{
|
||||||
return bufref->br_buf_free_count == buf_free_count
|
return bufref->br_buf_free_count == buf_free_count
|
||||||
? true
|
? true
|
||||||
: buf_valid(bufref->br_buf);
|
: buf_valid(bufref->br_buf) && bufref->br_fnum == bufref->br_buf->b_fnum;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Check that "buf" points to a valid buffer in the buffer list.
|
/// Check that "buf" points to a valid buffer in the buffer list.
|
||||||
@@ -1753,16 +1756,15 @@ void free_buf_options(buf_T *buf, int free_p_ff)
|
|||||||
clear_string_option(&buf->b_p_bkc);
|
clear_string_option(&buf->b_p_bkc);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* 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 buflist_getfile(int n, linenr_T lnum, int options, int forceit)
|
int buflist_getfile(int n, linenr_T lnum, int options, int forceit)
|
||||||
{
|
{
|
||||||
buf_T *buf;
|
buf_T *buf;
|
||||||
|
@@ -115,7 +115,7 @@ static inline void buf_set_changedtick(buf_T *const buf,
|
|||||||
do { \
|
do { \
|
||||||
win_T *save_curwin = NULL; \
|
win_T *save_curwin = NULL; \
|
||||||
tabpage_T *save_curtab = NULL; \
|
tabpage_T *save_curtab = NULL; \
|
||||||
bufref_T save_curbuf = { NULL, 0 }; \
|
bufref_T save_curbuf = { NULL, 0, 0 }; \
|
||||||
switch_to_win_for_buf(b, &save_curwin, &save_curtab, &save_curbuf); \
|
switch_to_win_for_buf(b, &save_curwin, &save_curtab, &save_curbuf); \
|
||||||
code; \
|
code; \
|
||||||
restore_win_for_buf(save_curwin, save_curtab, &save_curbuf); \
|
restore_win_for_buf(save_curwin, save_curtab, &save_curbuf); \
|
||||||
|
@@ -12,6 +12,7 @@ typedef struct file_buffer buf_T; // Forward declaration
|
|||||||
// 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;
|
||||||
|
|
||||||
|
@@ -568,7 +568,7 @@ EXTERN int keep_filetype INIT(= FALSE); /* value for did_filetype when
|
|||||||
|
|
||||||
// When deleting the current buffer, another one must be loaded.
|
// When deleting the current buffer, another one must be loaded.
|
||||||
// If we know which one is preferred, au_new_curbuf is set to it.
|
// If we know which one is preferred, au_new_curbuf is set to it.
|
||||||
EXTERN bufref_T au_new_curbuf INIT(= { NULL, 0 });
|
EXTERN bufref_T au_new_curbuf INIT(= { NULL, 0, 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
|
||||||
|
@@ -191,7 +191,7 @@ typedef struct {
|
|||||||
// 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
|
||||||
@@ -2330,9 +2330,7 @@ void qf_history(exarg_T *eap)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/// Free all the entries in the error list "idx".
|
||||||
* Free error list "idx".
|
|
||||||
*/
|
|
||||||
static void qf_free(qf_info_T *qi, int idx)
|
static void qf_free(qf_info_T *qi, int idx)
|
||||||
{
|
{
|
||||||
qfline_T *qfp;
|
qfline_T *qfp;
|
||||||
|
Reference in New Issue
Block a user