patch 9.1.1387: memory leak when buflist_new() fails to reuse curbuf Commit: https://github.com/vim/vim/commit/0077282c8209e5a3893d74a0176ab21895c5de4e Author: Sean Dewar <6256228+seande...@users.noreply.github.com> Date: Wed May 14 20:16:52 2025 +0200
patch 9.1.1387: memory leak when buflist_new() fails to reuse curbuf Problem: buflist_new() leaks ffname and fails to reuse curbuf when autocommands from buf_freeall change curbuf. Plus, a new buffer is not allocated in this case, despite what the comment above claims. Solution: Remove the condition so ffname is not leaked and so a new buffer is allocated like before v8.2.4791. It should not be possible for undo_ftplugin or buf_freeall autocommands to delete the buffer as they set b_locked, but to stay consistent with other uses of buf_freeall, guard against that anyway (Sean Dewar). Note that buf is set to NULL if it was deleted to guard against the (rare) possibility of messing up the "buf != curbuf" condition below if a new buffer happens to be allocated at the same address. closes: #17319 Signed-off-by: Sean Dewar <6256228+seande...@users.noreply.github.com> Signed-off-by: Christian Brabandt <c...@256bit.org> diff --git a/src/buffer.c b/src/buffer.c index b4481b2f1..49ec77c7b 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -2220,13 +2220,14 @@ buflist_new( buf = NULL; if ((flags & BLN_CURBUF) && curbuf_reusable()) { + bufref_T bufref; + buf = curbuf; + set_bufref(&bufref, buf); trigger_undo_ftplugin(buf, curwin); // It's like this buffer is deleted. Watch out for autocommands that // change curbuf! If that happens, allocate a new buffer anyway. buf_freeall(buf, BFA_WIPE | BFA_DEL); - if (buf != curbuf) // autocommands deleted the buffer! - return NULL; #ifdef FEAT_EVAL if (aborting()) // autocmds may abort script processing { @@ -2234,6 +2235,8 @@ buflist_new( return NULL; } #endif + if (!bufref_valid(&bufref)) + buf = NULL; // buf was deleted; allocate a new buffer } if (buf != curbuf || curbuf == NULL) { diff --git a/src/testdir/test_autocmd.vim b/src/testdir/test_autocmd.vim index db5558304..26f714565 100644 --- a/src/testdir/test_autocmd.vim +++ b/src/testdir/test_autocmd.vim @@ -5390,4 +5390,29 @@ func Test_eventignorewin_non_current() %bw! endfunc +func Test_reuse_curbuf_leak() + new bar + let s:bar_buf = bufnr() + augroup testing + autocmd! + autocmd BufDelete * ++once let s:triggered = 1 | execute s:bar_buf 'buffer' + augroup END + enew + let empty_buf = bufnr() + + " Old curbuf should be reused, firing BufDelete. As BufDelete changes curbuf, + " reusing the buffer would fail and leak the ffname. + edit foo + call assert_equal(1, s:triggered) + " Wasn't reused because the buffer changed, but buffer "foo" is still created. + call assert_equal(1, bufexists(empty_buf)) + call assert_notequal(empty_buf, bufnr()) + call assert_equal('foo', bufname()) + call assert_equal('bar', bufname(s:bar_buf)) + + unlet! s:bar_buf s:triggered + call CleanUpTestAuGroup() + %bw! +endfunc + " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/version.c b/src/version.c index 78a6e7b7c..7e6e862de 100644 --- a/src/version.c +++ b/src/version.c @@ -704,6 +704,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 1387, /**/ 1386, /**/ -- -- You received this message from the "vim_dev" maillist. Do not top-post! Type your reply below the text you are replying to. For more information, visit http://www.vim.org/maillist.php --- You received this message because you are subscribed to the Google Groups "vim_dev" group. To unsubscribe from this group and stop receiving emails from it, send an email to vim_dev+unsubscr...@googlegroups.com. To view this discussion visit https://groups.google.com/d/msgid/vim_dev/E1uFGrt-00AaoL-Gp%40256bit.org.