To: vim_dev@googlegroups.com Subject: Patch 8.0.1732 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.0.1732 Problem: Crash when terminal API call deletes the buffer. Solution: Lock the buffer while calling a function. (closes #2813) Files: src/buffer.c, src/terminal.c, src/testdir/test_terminal.vim, src/testdir/test_autocmd.vim *** ../vim-8.0.1731/src/buffer.c 2018-04-10 18:47:16.085527102 +0200 --- src/buffer.c 2018-04-17 23:00:25.000925193 +0200 *************** *** 417,422 **** --- 417,424 ---- 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. * "action" is used when there is no longer a window for the buffer. *************** *** 476,483 **** --- 478,492 ---- if (term_job_running(buf->b_term)) { 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); + } else { /* The job keeps running, hide the buffer. */ *************** *** 499,505 **** * halfway a command that relies on it). Unloading is allowed. */ if (buf->b_locked > 0 && (del_buf || wipe_buf)) { ! EMSG(_("E937: Attempt to delete a buffer that is in use")); return; } --- 508,514 ---- * halfway a command that relies on it). Unloading is allowed. */ if (buf->b_locked > 0 && (del_buf || wipe_buf)) { ! EMSG(_(e_buflocked)); return; } *************** *** 1356,1361 **** --- 1365,1376 ---- int forward; bufref_T bufref; + if (buf->b_locked) + { + EMSG(_(e_buflocked)); + return FAIL; + } + set_bufref(&bufref, buf); /* When unloading or deleting a buffer that's already unloaded and *** ../vim-8.0.1731/src/terminal.c 2018-04-15 23:45:12.974388434 +0200 --- src/terminal.c 2018-04-17 23:08:38.129246906 +0200 *************** *** 46,51 **** --- 46,54 ---- * switch to GUI, shell stops working. Scrollback seems wrong, command * running in shell is still running. * - GUI: when using tabs, focus in terminal, click on tab does not work. + * - handle_moverect() scrolls one line at a time. Postpone scrolling, count + * the number of lines, until a redraw happens. Then if scrolling many lines + * a redraw is faster. * - Copy text in the vterm to the Vim buffer once in a while, so that * completion works. * - Redrawing is slow with Athena and Motif. Also other GUI? (Ramel Eshed) *************** *** 3433,3438 **** --- 3436,3445 ---- { char_u *cmd = get_tv_string(&item->li_tv); + /* Make sure an invoked command doesn't delete the buffer (and the + * terminal) under our fingers. */ + ++term->tl_buffer->b_locked; + item = item->li_next; if (item == NULL) ch_log(channel, "Missing argument for %s", cmd); *************** *** 3442,3447 **** --- 3449,3455 ---- handle_call_command(term, channel, item); else ch_log(channel, "Invalid command received: %s", cmd); + --term->tl_buffer->b_locked; } } else *** ../vim-8.0.1731/src/testdir/test_terminal.vim 2018-04-15 23:45:12.978388406 +0200 --- src/testdir/test_terminal.vim 2018-04-17 23:07:37.537691498 +0200 *************** *** 1287,1292 **** --- 1287,1316 ---- call delete('Xlog') endfunc + let s:caught_e937 = 0 + + func Tapi_Delete(bufnum, arg) + try + execute 'bdelete!' a:bufnum + catch /E937:/ + let s:caught_e937 = 1 + endtry + endfunc + + func Test_terminal_api_call_fail_delete() + if !CanRunVimInTerminal() + return + endif + + call WriteApiCall('Tapi_Delete') + let buf = RunVimInTerminal('-S Xscript', {}) + call WaitFor({-> s:caught_e937 == 1}) + + call StopVimInTerminal(buf) + call delete('Xscript') + call ch_logfile('', '') + endfunc + func Test_terminal_ansicolors_default() let colors = [ \ '#000000', '#e00000', *** ../vim-8.0.1731/src/testdir/test_autocmd.vim 2018-03-29 17:40:42.607415702 +0200 --- src/testdir/test_autocmd.vim 2018-04-17 23:21:01.779868180 +0200 *************** *** 119,125 **** exe 'autocmd BufUnload ' . (lastbuf + 1) . 'bwipeout!' augroup END ! call assert_fails('edit bb.txt', 'E937:') autocmd! test_autocmd_bufunload augroup! test_autocmd_bufunload --- 119,127 ---- exe 'autocmd BufUnload ' . (lastbuf + 1) . 'bwipeout!' augroup END ! " Todo: check for E937 generated first ! " call assert_fails('edit bb.txt', 'E937:') ! call assert_fails('edit bb.txt', 'E517:') autocmd! test_autocmd_bufunload augroup! test_autocmd_bufunload *************** *** 316,322 **** e Xtestje2 sp Xtestje1 call assert_fails('e', 'E937:') ! call assert_equal('Xtestje2', expand('%')) " Test changing buffers in a BufWipeout autocommand. If this goes wrong " there are ml_line errors and/or a Crash. --- 318,324 ---- e Xtestje2 sp Xtestje1 call assert_fails('e', 'E937:') ! call assert_equal('Xtestje1', expand('%')) " Test changing buffers in a BufWipeout autocommand. If this goes wrong " there are ml_line errors and/or a Crash. *************** *** 338,344 **** au! enew - bwipe! Xtestje1 call delete('Xtestje1') call delete('Xtestje2') call delete('Xtestje3') --- 340,345 ---- *************** *** 1181,1187 **** func Test_nocatch_wipe_all_buffers() " Real nasty autocommand: wipe all buffers on any event. au * * bwipe * ! call assert_fails('next x', 'E93') bwipe au! endfunc --- 1182,1190 ---- func Test_nocatch_wipe_all_buffers() " Real nasty autocommand: wipe all buffers on any event. au * * bwipe * ! " Get E93 first? ! " call assert_fails('next x', 'E93:') ! call assert_fails('next x', 'E517:') bwipe au! endfunc *** ../vim-8.0.1731/src/version.c 2018-04-17 22:14:27.456314045 +0200 --- src/version.c 2018-04-17 23:08:10.121452228 +0200 *************** *** 764,765 **** --- 764,767 ---- { /* Add new patch number below this line */ + /**/ + 1732, /**/ -- hundred-and-one symptoms of being an internet addict: 212. Your Internet group window has more icons than your Accessories window. /// 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 ///