]> granicus.if.org Git - vim/commitdiff
patch 8.0.0607: after :bwipe + :new bufref might still be valid v8.0.0607
authorBram Moolenaar <Bram@vim.org>
Sun, 4 Jun 2017 12:58:02 +0000 (14:58 +0200)
committerBram Moolenaar <Bram@vim.org>
Sun, 4 Jun 2017 12:58:02 +0000 (14:58 +0200)
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.

src/buffer.c
src/globals.h
src/if_py_both.h
src/quickfix.c
src/structs.h
src/version.c

index 83d74a3795603ba58fee1661b501c3d14456616b..a57d2f6435efbe56ee7c2f37fa2a2e14c4239216 100644 (file)
@@ -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)
index 1d67b0d7af50d33933b31779d8bbb2e4473aefaf..7bc5471769adb01b972beb7e8e2c7b08459f039c 100644 (file)
@@ -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
index 78c70e700bd387b0bbc616c47d7618900d62a6eb..b6f232e4954e5d18f2e4a3083b6b3599f69b97e2 100644 (file)
@@ -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;
 
index 6de55f75dc7f51421fcdbf3ae6ebeb86f2d792b0..e330e6e9befa38a01dd9501952cdd9247e1853cb 100644 (file)
@@ -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)
index 0175017423c72d15c3b2c9421009b7e4150e44ee..d79b2253f730562e9618f5c891ae48bb3d63688d 100644 (file)
@@ -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;
 
index 0daa3497d6595b34ca6a66dae1689a35da8dd155..e96a388e201b71f5af9f2e93b97bedca7e84e70d 100644 (file)
@@ -764,6 +764,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    607,
 /**/
     606,
 /**/