fix(terminal): set b_locked when setting &buftype (#37787)

Problem: heap use-after-free if OptionSet autocommands from setting a terminal's
&buftype wipe the buffer.

Solution: set b_locked during OptionSet for &buftype.
This commit is contained in:
Sean Dewar
2026-02-09 12:51:04 +00:00
committed by GitHub
parent 7ee41a4b33
commit 1b627f6c59
2 changed files with 8 additions and 1 deletions

View File

@@ -580,7 +580,9 @@ void terminal_open(Terminal **termpp, buf_T *buf)
assert(term->invalid_start >= 0);
}
refresh_screen(term, buf);
buf->b_locked++;
set_option_value(kOptBuftype, STATIC_CSTR_AS_OPTVAL("terminal"), OPT_LOCAL);
buf->b_locked--;
if (buf->b_ffname != NULL) {
buf_set_term_title(buf, buf->b_ffname, strlen(buf->b_ffname));

View File

@@ -1165,8 +1165,13 @@ describe(':terminal buffer', function()
eq({ mode = 'nt', blocking = false }, api.nvim_get_mode())
end)
it('does not allow b:term_title watcher to delete buffer', function()
it('does not allow OptionSet or b:term_title watcher to delete buffer', function()
local au = api.nvim_create_autocmd('OptionSet', { command = 'bwipeout!' })
local chan = api.nvim_open_term(0, {})
matches('^E937: ', api.nvim_get_vvar('errmsg'))
api.nvim_del_autocmd(au)
api.nvim_set_vvar('errmsg', '')
api.nvim_chan_send(chan, '\027]2;SOME_TITLE\007')
eq('SOME_TITLE', api.nvim_buf_get_var(0, 'term_title'))
command([[call dictwatcheradd(b:, 'term_title', {-> execute('bwipe!')})]])