mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
coverity/331378: Fix inserting new decor provider
Since the providers are ordered by ns_id, inserting a new provider may require shifting existing providers around to maintain this ordering. When this happens, we need to allocate a new element at the end of the vector and then shift the larger elements to the right. Rather than iterating (incorrectly) with a loop and copying each item, use memmove to copy the entire block.
This commit is contained in:
parent
71107e12c7
commit
833a6fcb60
@ -383,8 +383,9 @@ void decor_add_ephemeral(int start_row, int start_col, int end_row, int end_col,
|
||||
|
||||
DecorProvider *get_decor_provider(NS ns_id, bool force)
|
||||
{
|
||||
ssize_t i;
|
||||
for (i = 0; i < (ssize_t)kv_size(decor_providers); i++) {
|
||||
size_t i;
|
||||
size_t len = kv_size(decor_providers);
|
||||
for (i = 0; i < len; i++) {
|
||||
DecorProvider *item = &kv_A(decor_providers, i);
|
||||
if (item->ns_id == ns_id) {
|
||||
return item;
|
||||
@ -397,12 +398,16 @@ DecorProvider *get_decor_provider(NS ns_id, bool force)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (ssize_t j = (ssize_t)kv_size(decor_providers)-1; j >= i; j++) {
|
||||
// allocates if needed:
|
||||
(void)kv_a(decor_providers, (size_t)j+1);
|
||||
kv_A(decor_providers, (size_t)j+1) = kv_A(decor_providers, j);
|
||||
// Adding a new provider, so allocate room in the vector
|
||||
(void)kv_a(decor_providers, len);
|
||||
if (i < len) {
|
||||
// New ns_id needs to be inserted between existing providers to maintain
|
||||
// ordering, so shift other providers with larger ns_id
|
||||
memmove(&kv_A(decor_providers, i + 1),
|
||||
&kv_A(decor_providers, i),
|
||||
(len - i) * sizeof(kv_a(decor_providers, i)));
|
||||
}
|
||||
DecorProvider *item = &kv_a(decor_providers, (size_t)i);
|
||||
DecorProvider *item = &kv_a(decor_providers, i);
|
||||
*item = DECORATION_PROVIDER_INIT(ns_id);
|
||||
|
||||
return item;
|
||||
|
@ -66,6 +66,18 @@ describe('decorations providers', function()
|
||||
expect_events(expected, actual, "beam trace")
|
||||
end
|
||||
|
||||
it('does not OOM when inserting, rather than appending, to the decoration provider vector', function()
|
||||
-- Add a dummy decoration provider with a larger ns id than what setup_provider() creates.
|
||||
-- This forces get_decor_provider() to insert into the providers vector,
|
||||
-- rather than append, which used to spin in an infinite loop allocating
|
||||
-- memory until nvim crashed/was killed.
|
||||
setup_provider([[
|
||||
local ns2 = a.nvim_create_namespace "ns2"
|
||||
a.nvim_set_decoration_provider(ns2, {})
|
||||
]])
|
||||
helpers.assert_alive()
|
||||
end)
|
||||
|
||||
it('leave a trace', function()
|
||||
insert(mulholland)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user