summaryrefslogtreecommitdiff
path: root/data/vim/patches/8.1.0342
blob: 3ea1ac3f5ec456e5e4ea0a37c471a267babb11dd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
To: vim_dev@googlegroups.com
Subject: Patch 8.1.0342
Fcc: outbox
From: Bram Moolenaar <Bram@moolenaar.net>
Mime-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
------------

Patch 8.1.0342
Problem:    Crash when a callback deletes a window that is being used.
Solution:   Do not unload a buffer that is being displayed while redrawing the
            screen. Also avoid invoking callbacks while redrawing.
            (closes #2107)
Files:	    src/buffer.c, src/misc2.c


*** ../vim-8.1.0341/src/buffer.c	2018-08-21 18:50:11.153501902 +0200
--- src/buffer.c	2018-09-01 15:16:57.753412395 +0200
***************
*** 412,418 ****
  	hash_remove(&buf_hashtab, hi);
  }
  
! static char *e_buflocked = N_("E937: Attempt to delete a buffer that is in use");
  
  /*
   * Close the link to a buffer.
--- 412,439 ----
  	hash_remove(&buf_hashtab, hi);
  }
  
! /*
!  * Return TRUE when buffer "buf" can be unloaded.
!  * Give an error message and return FALSE when the buffer is locked or the
!  * screen is being redrawn and the buffer is in a window.
!  */
!     static int
! can_unload_buffer(buf_T *buf)
! {
!     int	    can_unload = !buf->b_locked;
! 
!     if (can_unload && updating_screen)
!     {
! 	win_T	*wp;
! 
! 	FOR_ALL_WINDOWS(wp)
! 	    if (wp->w_buffer == buf)
! 		can_unload = FALSE;
!     }
!     if (!can_unload)
! 	EMSG(_("E937: Attempt to delete a buffer that is in use"));
!     return can_unload;
! }
  
  /*
   * Close the link to a buffer.
***************
*** 474,484 ****
  	{
  	    if (wipe_buf || unload_buf)
  	    {
! 		if (buf->b_locked)
! 		{
! 		    EMSG(_(e_buflocked));
  		    return;
! 		}
  		/* Wiping out or unloading a terminal buffer kills the job. */
  		free_terminal(buf);
  	    }
--- 495,503 ----
  	{
  	    if (wipe_buf || unload_buf)
  	    {
! 		if (!can_unload_buffer(buf))
  		    return;
! 
  		/* Wiping out or unloading a terminal buffer kills the job. */
  		free_terminal(buf);
  	    }
***************
*** 501,511 ****
  
      /* Disallow deleting the buffer when it is locked (already being closed or
       * halfway a command that relies on it). Unloading is allowed. */
!     if (buf->b_locked > 0 && (del_buf || wipe_buf))
!     {
! 	EMSG(_(e_buflocked));
  	return;
-     }
  
      /* check no autocommands closed the window */
      if (win != NULL && win_valid_any_tab(win))
--- 520,527 ----
  
      /* Disallow deleting the buffer when it is locked (already being closed or
       * halfway a command that relies on it). Unloading is allowed. */
!     if ((del_buf || wipe_buf) && !can_unload_buffer(buf))
  	return;
  
      /* check no autocommands closed the window */
      if (win != NULL && win_valid_any_tab(win))
***************
*** 1196,1203 ****
      return errormsg;
  }
  
- static int	empty_curbuf(int close_others, int forceit, int action);
- 
  /*
   * Make the current buffer empty.
   * Used when it is wiped out and it's the last buffer.
--- 1212,1217 ----
***************
*** 1238,1243 ****
--- 1252,1258 ----
  	need_fileinfo = FALSE;
      return retval;
  }
+ 
  /*
   * Implementation of the commands for the buffer list.
   *
***************
*** 1359,1369 ****
  	int	forward;
  	bufref_T bufref;
  
! 	if (buf->b_locked)
! 	{
! 	    EMSG(_(e_buflocked));
  	    return FAIL;
- 	}
  
  	set_bufref(&bufref, buf);
  
--- 1374,1381 ----
  	int	forward;
  	bufref_T bufref;
  
! 	if (!can_unload_buffer(buf))
  	    return FAIL;
  
  	set_bufref(&bufref, buf);
  
*** ../vim-8.1.0341/src/misc2.c	2018-07-29 16:09:14.636945607 +0200
--- src/misc2.c	2018-09-01 15:07:10.019535433 +0200
***************
*** 6366,6398 ****
  {
      win_T *old_curwin = curwin;
  
!     /* For Win32 mch_breakcheck() does not check for input, do it here. */
  # if defined(WIN32) && defined(FEAT_JOB_CHANNEL)
      channel_handle_events(FALSE);
  # endif
  
  # ifdef FEAT_NETBEANS_INTG
!     /* Process the queued netbeans messages. */
      netbeans_parse_messages();
  # endif
  # ifdef FEAT_JOB_CHANNEL
!     /* Write any buffer lines still to be written. */
      channel_write_any_lines();
  
!     /* Process the messages queued on channels. */
      channel_parse_messages();
  # endif
  # if defined(FEAT_CLIENTSERVER) && defined(FEAT_X11)
!     /* Process the queued clientserver messages. */
      server_parse_messages();
  # endif
  # ifdef FEAT_JOB_CHANNEL
!     /* Check if any jobs have ended. */
      job_check_ended();
  # endif
  
!     /* If the current window changed we need to bail out of the waiting loop.
!      * E.g. when a job exit callback closes the terminal window. */
      if (curwin != old_curwin)
  	ins_char_typebuf(K_IGNORE);
  }
--- 6366,6403 ----
  {
      win_T *old_curwin = curwin;
  
!     // Do not handle messages while redrawing, because it may cause buffers to
!     // change or be wiped while they are being redrawn.
!     if (updating_screen)
! 	return;
! 
!     // For Win32 mch_breakcheck() does not check for input, do it here.
  # if defined(WIN32) && defined(FEAT_JOB_CHANNEL)
      channel_handle_events(FALSE);
  # endif
  
  # ifdef FEAT_NETBEANS_INTG
!     // Process the queued netbeans messages.
      netbeans_parse_messages();
  # endif
  # ifdef FEAT_JOB_CHANNEL
!     // Write any buffer lines still to be written.
      channel_write_any_lines();
  
!     // Process the messages queued on channels.
      channel_parse_messages();
  # endif
  # if defined(FEAT_CLIENTSERVER) && defined(FEAT_X11)
!     // Process the queued clientserver messages.
      server_parse_messages();
  # endif
  # ifdef FEAT_JOB_CHANNEL
!     // Check if any jobs have ended.
      job_check_ended();
  # endif
  
!     // If the current window changed we need to bail out of the waiting loop.
!     // E.g. when a job exit callback closes the terminal window.
      if (curwin != old_curwin)
  	ins_char_typebuf(K_IGNORE);
  }
*** ../vim-8.1.0341/src/version.c	2018-08-31 23:06:18.735841246 +0200
--- src/version.c	2018-09-01 15:02:16.242604587 +0200
***************
*** 796,797 ****
--- 796,799 ----
  {   /* Add new patch number below this line */
+ /**/
+     342,
  /**/

-- 
hundred-and-one symptoms of being an internet addict:
5. You find yourself brainstorming for new subjects to search.

 /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net   \\\
///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\  an exciting new programming language -- http://www.Zimbu.org        ///
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///