diff options
| author | Eliseo Martínez <eliseomarmol@gmail.com> | 2014-11-08 21:14:33 +0100 | 
|---|---|---|
| committer | Eliseo Martínez <eliseomarmol@gmail.com> | 2014-11-11 01:43:12 +0100 | 
| commit | d6472f459bc531bf6e24c3bcc1916dba16ba1f10 (patch) | |
| tree | 8930112d5102462fdc2c67ebfd99627a3b314621 /src/nvim/ex_getln.c | |
| parent | ea1f883b199e957134bcb115184280e7122cadbb (diff) | |
| download | rneovim-d6472f459bc531bf6e24c3bcc1916dba16ba1f10.tar.gz rneovim-d6472f459bc531bf6e24c3bcc1916dba16ba1f10.tar.bz2 rneovim-d6472f459bc531bf6e24c3bcc1916dba16ba1f10.zip | |
Fix warnings: ex_getln.c: init_history(): Double free: FP.
Problem    : Double free @ 4249.
Diagnostic : False positive.
Rationale  : Codepath leading to error contains two consecutive
             iterations in which `if (--j < 0)` is true.
             That executes `free` two consecutive times with the same
             value (hislen - 1) for j, with leads to double free.
             Now, that can only happen with j == 0 && hislen == 1.
             And that would imply j == hisidx[type] too, which would
             take the following break.
             So, the error codepath cannot really happen, but the
             compiler cannot deduce the last implication.
Resolution : We have two possible solutions for this:
             1.- Comparing value of j before and after updating it,
                 and breaking out of iteration if equal.
                 That changes nothing in functionality, but teaches the
                 compiler his proposed error codepath is impossible.
             2.- Nullify pointer after freeing.
                 This way, the compiler still thinks his error codepath
                 is possible, but it's not an error anymore, as
                 free(NULL) is a no-op.
             We opt for solution 2, as solution 1 requires adding
             logic that adds nothing (and having to explain that clearly
             in aside comments) just for the purpose of silencing
             warning. On the other hand, solution 2 improves the code,
             adding something considered good practice in any case,
             and therefore doesn't require further explanation.
Diffstat (limited to 'src/nvim/ex_getln.c')
| -rw-r--r-- | src/nvim/ex_getln.c | 4 | 
1 files changed, 3 insertions, 1 deletions
| diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c index b8d8837092..5feff4d456 100644 --- a/src/nvim/ex_getln.c +++ b/src/nvim/ex_getln.c @@ -4245,8 +4245,10 @@ void init_history(void)            for (i = newlen - 1;; --i) {              if (i >= 0)                         /* copy newest entries */                temp[i] = history[type][j]; -            else                                /* remove older entries */ +            else {                              /* remove older entries */                free(history[type][j].hisstr); +              history[type][j].hisstr = NULL; +            }              if (--j < 0)                j = hislen - 1;              if (j == hisidx[type]) | 
