comparison src/buffer.c @ 13720:7d2039b2ecc8 v8.0.1732

patch 8.0.1732: crash when terminal API call deletes the buffer commit https://github.com/vim/vim/commit/a997b45c7e350ea5b378ca0c52ed3d4cc610975c Author: Bram Moolenaar <Bram@vim.org> Date: Tue Apr 17 23:24:06 2018 +0200 patch 8.0.1732: crash when terminal API call deletes the buffer Problem: Crash when terminal API call deletes the buffer. Solution: Lock the buffer while calling a function. (closes https://github.com/vim/vim/issues/2813)
author Christian Brabandt <cb@256bit.org>
date Tue, 17 Apr 2018 23:30:07 +0200
parents cec5137d5332
children 3be5e8306a3e
comparison
equal deleted inserted replaced
13719:fb1a9741c1c5 13720:7d2039b2ecc8
415 415
416 if (!HASHITEM_EMPTY(hi)) 416 if (!HASHITEM_EMPTY(hi))
417 hash_remove(&buf_hashtab, hi); 417 hash_remove(&buf_hashtab, hi);
418 } 418 }
419 419
420 static char *e_buflocked = N_("E937: Attempt to delete a buffer that is in use");
421
420 /* 422 /*
421 * Close the link to a buffer. 423 * Close the link to a buffer.
422 * "action" is used when there is no longer a window for the buffer. 424 * "action" is used when there is no longer a window for the buffer.
423 * It can be: 425 * It can be:
424 * 0 buffer becomes hidden 426 * 0 buffer becomes hidden
474 if (bt_terminal(buf) && (buf->b_nwindows == 1 || del_buf)) 476 if (bt_terminal(buf) && (buf->b_nwindows == 1 || del_buf))
475 { 477 {
476 if (term_job_running(buf->b_term)) 478 if (term_job_running(buf->b_term))
477 { 479 {
478 if (wipe_buf || unload_buf) 480 if (wipe_buf || unload_buf)
481 {
482 if (buf->b_locked)
483 {
484 EMSG(_(e_buflocked));
485 return;
486 }
479 /* Wiping out or unloading a terminal buffer kills the job. */ 487 /* Wiping out or unloading a terminal buffer kills the job. */
480 free_terminal(buf); 488 free_terminal(buf);
489 }
481 else 490 else
482 { 491 {
483 /* The job keeps running, hide the buffer. */ 492 /* The job keeps running, hide the buffer. */
484 del_buf = FALSE; 493 del_buf = FALSE;
485 unload_buf = FALSE; 494 unload_buf = FALSE;
497 506
498 /* Disallow deleting the buffer when it is locked (already being closed or 507 /* Disallow deleting the buffer when it is locked (already being closed or
499 * halfway a command that relies on it). Unloading is allowed. */ 508 * halfway a command that relies on it). Unloading is allowed. */
500 if (buf->b_locked > 0 && (del_buf || wipe_buf)) 509 if (buf->b_locked > 0 && (del_buf || wipe_buf))
501 { 510 {
502 EMSG(_("E937: Attempt to delete a buffer that is in use")); 511 EMSG(_(e_buflocked));
503 return; 512 return;
504 } 513 }
505 514
506 /* check no autocommands closed the window */ 515 /* check no autocommands closed the window */
507 if (win != NULL && win_valid_any_tab(win)) 516 if (win != NULL && win_valid_any_tab(win))
1353 */ 1362 */
1354 if (unload) 1363 if (unload)
1355 { 1364 {
1356 int forward; 1365 int forward;
1357 bufref_T bufref; 1366 bufref_T bufref;
1367
1368 if (buf->b_locked)
1369 {
1370 EMSG(_(e_buflocked));
1371 return FAIL;
1372 }
1358 1373
1359 set_bufref(&bufref, buf); 1374 set_bufref(&bufref, buf);
1360 1375
1361 /* When unloading or deleting a buffer that's already unloaded and 1376 /* When unloading or deleting a buffer that's already unloaded and
1362 * unlisted: fail silently. */ 1377 * unlisted: fail silently. */