diff --git a/src/nvim/api/extmark.c b/src/nvim/api/extmark.c index b1ade3a0b3d..d6d7be8e3a5 100644 --- a/src/nvim/api/extmark.c +++ b/src/nvim/api/extmark.c @@ -1251,6 +1251,7 @@ void nvim__ns_set(Integer ns_id, Dict(ns_opts) *opts, Error *err) win_T *wp = find_window_by_handle((Window)win, err); if (!wp) { + set_destroy(ptr_t, &windows); return; } diff --git a/test/functional/ui/decorations_spec.lua b/test/functional/ui/decorations_spec.lua index eae37ed7167..6a0ce007ecb 100644 --- a/test/functional/ui/decorations_spec.lua +++ b/test/functional/ui/decorations_spec.lua @@ -8431,6 +8431,13 @@ describe('decorations: window scoped', function() return api.nvim_buf_set_extmark(0, ns, line, col, opts) end + it('rejects an invalid window without leaking the window set', function() + -- The bad handle comes second, so the set already owns an allocation by + -- the time validation fails and returns. + eq('Invalid window id: 9999', t.pcall_err(api.nvim__ns_set, ns, { wins = { api.nvim_get_current_win(), 9999 } })) + assert_alive() + end) + it('hl_group', function() set_extmark(0, 0, { hl_group = 'Comment',