summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2017-06-04 14:58:02 +0200
committerBram Moolenaar <Bram@vim.org>2017-06-04 14:58:02 +0200
commit45e5fd135da5710f24a1acc142692f120f8b0b78 (patch)
treedb3f8e21176d61550e6c7dbb75dc69faf614c272
parent6e62da3e14d32f76f60d5cc8b267059923842f17 (diff)
downloadvim-git-8.0.0607.tar.gz
patch 8.0.0607: after :bwipe + :new bufref might still be validv8.0.0607
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.
-rw-r--r--src/buffer.c19
-rw-r--r--src/globals.h2
-rw-r--r--src/if_py_both.h6
-rw-r--r--src/quickfix.c6
-rw-r--r--src/structs.h4
-rw-r--r--src/version.c2
6 files changed, 24 insertions, 15 deletions
diff --git a/src/buffer.c b/src/buffer.c
index 83d74a379..a57d2f643 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -372,18 +372,23 @@ open_buffer(
set_bufref(bufref_T *bufref, buf_T *buf)
{
bufref->br_buf = buf;
+ bufref->br_fnum = buf->b_fnum;
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.
+ * 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
bufref_valid(bufref_T *bufref)
{
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
- * set linenr to lnum or altfpos.lnum if lnum == 0
- * also set cursor column to altfpos.col if 'startofline' is not set.
+ * Get alternate file "n".
+ * Set linenr to "lnum" or altfpos.lnum if "lnum" == 0.
+ * Also set cursor column to altfpos.col if 'startofline' is not set.
* if (options & GETF_SETMARK) call setpcmark()
* if (options & GETF_ALT) we are jumping to an alternate file.
* 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(
@@ -2999,7 +3004,7 @@ buflist_findlnum(buf_T *buf)
#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
buflist_list(exarg_T *eap)
diff --git a/src/globals.h b/src/globals.h
index 1d67b0d7a..7bc547176 100644
--- a/src/globals.h
+++ b/src/globals.h
@@ -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
* 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
* buffer/window. but link it in the list starting with
diff --git a/src/if_py_both.h b/src/if_py_both.h
index 78c70e700..b6f232e49 100644
--- a/src/if_py_both.h
+++ b/src/if_py_both.h
@@ -4311,7 +4311,7 @@ restore_win_for_buf(
static int
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;
tabpage_T *save_curtab = NULL;
@@ -4415,7 +4415,7 @@ SetBufferLineList(
PyObject *list,
PyInt *len_change)
{
- bufref_T save_curbuf = {NULL, 0};
+ bufref_T save_curbuf = {NULL, 0, 0};
win_T *save_curwin = NULL;
tabpage_T *save_curtab = NULL;
@@ -4616,7 +4616,7 @@ SetBufferLineList(
static int
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;
tabpage_T *save_curtab = NULL;
diff --git a/src/quickfix.c b/src/quickfix.c
index 6de55f75d..e330e6e9b 100644
--- a/src/quickfix.c
+++ b/src/quickfix.c
@@ -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
* to make this a lot faster if there are multiple matches in the same file.
*/
-static char_u *qf_last_bufname = NULL;
-static bufref_T qf_last_bufref = {NULL, 0};
+static char_u *qf_last_bufname = NULL;
+static bufref_T qf_last_bufref = {NULL, 0, 0};
/*
* 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
qf_free(qf_info_T *qi, int idx)
diff --git a/src/structs.h b/src/structs.h
index 017501742..d79b2253f 100644
--- a/src/structs.h
+++ b/src/structs.h
@@ -69,11 +69,13 @@ typedef struct frame_S frame_T;
typedef int scid_T; /* script ID */
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.
*/
typedef struct {
buf_T *br_buf;
+ int br_fnum;
int br_buf_free_count;
} bufref_T;
diff --git a/src/version.c b/src/version.c
index 0daa3497d..e96a388e2 100644
--- a/src/version.c
+++ b/src/version.c
@@ -765,6 +765,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 607,
+/**/
606,
/**/
605,