aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJames McCoy <jamessan@jamessan.com>2021-05-05 21:26:51 -0400
committerJames McCoy <jamessan@jamessan.com>2021-05-06 18:56:56 -0400
commit833a6fcb6095254abae92a2309d7c3ce0e603bf3 (patch)
tree426f41debd34231fb5e86a0d26bc845edf366db5 /src
parent71107e12c7b68d8faf1bcc1a5794a55b21e146f3 (diff)
downloadrneovim-833a6fcb6095254abae92a2309d7c3ce0e603bf3.tar.gz
rneovim-833a6fcb6095254abae92a2309d7c3ce0e603bf3.tar.bz2
rneovim-833a6fcb6095254abae92a2309d7c3ce0e603bf3.zip
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.
Diffstat (limited to 'src')
-rw-r--r--src/nvim/decoration.c19
1 files changed, 12 insertions, 7 deletions
diff --git a/src/nvim/decoration.c b/src/nvim/decoration.c
index ca1d141dd8..f3000f4430 100644
--- a/src/nvim/decoration.c
+++ b/src/nvim/decoration.c
@@ -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;