From be3a4b6ca81c4e9dd3faa81dc01f53468ceed3ad Mon Sep 17 00:00:00 2001 From: Felipe Oliveira Carvalho Date: Mon, 9 Jun 2014 00:02:50 -0300 Subject: ga_growsize should be >= 1 I know it could be 0 sometimes. Running the tests with `assert(gap->ga_growsize > 0)` in ga_grow() crashes nvim while running the tests. - Add a setter for ga_growsize that checks whether the value passed is >=1 (log in case it's not) - log when ga_grow() tries to use a ga_growsize that's not >=1 - use GA_EMPTY_INIT_VALUE is many places --- src/nvim/garray.c | 34 ++++++++++++++++++++++++++++------ 1 file changed, 28 insertions(+), 6 deletions(-) (limited to 'src/nvim/garray.c') diff --git a/src/nvim/garray.c b/src/nvim/garray.c index ac5f9155b1..aaf1b3bd2b 100644 --- a/src/nvim/garray.c +++ b/src/nvim/garray.c @@ -6,6 +6,7 @@ #include "nvim/vim.h" #include "nvim/ascii.h" +#include "nvim/log.h" #include "nvim/misc2.h" #include "nvim/memory.h" #include "nvim/path.h" @@ -52,7 +53,21 @@ void ga_init(garray_T *gap, int itemsize, int growsize) gap->ga_maxlen = 0; gap->ga_len = 0; gap->ga_itemsize = itemsize; - gap->ga_growsize = growsize; + ga_set_growsize(gap, growsize); +} + +/// A setter for the growsize that guarantees it will be at least 1. +/// +/// @param gap +/// @param growsize +void ga_set_growsize(garray_T *gap, int growsize) +{ + if (growsize < 1) { + WLOG("trying to set an invalid ga_growsize: %d", growsize); + gap->ga_growsize = 1; + } else { + gap->ga_growsize = growsize; + } } /// Make room in growing array "gap" for at least "n" items. @@ -66,17 +81,24 @@ void ga_grow(garray_T *gap, int n) return; } - // the garray grows by at least growsize (do we have a MIN macro somewhere?) - n = (n < gap->ga_growsize) ? gap->ga_growsize : n; + if (gap->ga_growsize < 1) { + WLOG("ga_growsize(%d) is less than 1", gap->ga_growsize); + } + + // the garray grows by at least growsize + if (n < gap->ga_growsize) { + n = gap->ga_growsize; + } + int new_maxlen = gap->ga_len + n; - size_t new_size = (size_t)(gap->ga_itemsize * (gap->ga_len + n)); + size_t new_size = (size_t)(gap->ga_itemsize * new_maxlen); size_t old_size = (size_t)(gap->ga_itemsize * gap->ga_maxlen); // reallocate and clear the new memory - char_u *pp = xrealloc(gap->ga_data, new_size); + char *pp = xrealloc(gap->ga_data, new_size); memset(pp + old_size, 0, new_size - old_size); - gap->ga_maxlen = gap->ga_len + n; + gap->ga_maxlen = new_maxlen; gap->ga_data = pp; } -- cgit