Go to file
Justin M. Keyes aaf57a053d fix(coverity): false positives in kvec usages #41341
Coverity can't follow kv_ensure_space()'s `kv_roundup32()` bit math, so
every kv_concat_len() looks like an overrun; and it doesn't know
`kv_push()` allocates when `size == capacity`.

    _____________________________________________________________________________________________
    CID 653191:         Memory - illegal accesses  (OVERRUN)
    /src/nvim/input.c: 3536             in paste_store()
    3530
    3531         if (s > start) {
    3532           if (need_redo) {
    3533             kv_concat_len(redobuff.cur.keys, start, (size_t)(s - start));
    3534           }
    3535           if (need_record) {
    >>>     CID 653191:         Memory - illegal accesses  (OVERRUN)
    >>>     Overrunning dynamic array "recordbuff.items" at offset corresponding to index variable "recordbuff.size" through dereference in call to "memcpy".
    3536             kv_concat_len(recordbuff, start, (size_t)(s - start));
    3537           }
    3538         }
    3539
    3540         if (s < str_end) {
    3541           int c = (uint8_t)(*s++);

    _____________________________________________________________________________________________
    CID 653190:         Memory - illegal accesses  (OVERRUN)
    /src/nvim/input.c: 730             in redo_append_spec()
    724         return;
    725       }
    726
    727       while (*s != NUL) {
    728         if ((uint8_t)(*s) == K_SPECIAL && s[1] != NUL && s[2] != NUL) {
    729           // Insert special key literally.
    >>>     CID 653190:         Memory - illegal accesses  (OVERRUN)
    >>>     Overrunning dynamic array "redobuff.cur.keys.items" at offset corresponding to index variable "redobuff.cur.keys.size" through dereference in call to "memcpy".
    730           kv_concat_len(redobuff.cur.keys, s, 3);
    731           s += 3;
    732         } else {
    733           sb_add_char(&redobuff.cur.keys, mb_cptr2char_adv(&s));
    734         }
    735       }

    CID 653189:         (OVERRUN)
    /src/nvim/input.c: 3533           in paste_store()
    /src/nvim/input.c: 3536           in paste_store()

    _____________________________________________________________________________________________
    CID 653189:           (OVERRUN)
    /src/nvim/input.c: 3533             in paste_store()
    3527                && *s != NL && !(crlf && *s == CAR)) {
    3528           s++;
    3529         }
    3530
    3531         if (s > start) {
    3532           if (need_redo) {
    >>>     CID 653189:           (OVERRUN)
    >>>     Overrunning dynamic array "redobuff.cur.keys.items" at offset corresponding to index variable "redobuff.cur.keys.size" through dereference in call to "memcpy".
    3533             kv_concat_len(redobuff.cur.keys, start, (size_t)(s - start));
    3534           }
    3535           if (need_record) {
    3536             kv_concat_len(recordbuff, start, (size_t)(s - start));
    3537           }
    3538         }
    /src/nvim/input.c: 3536             in paste_store()
    3530
    3531         if (s > start) {
    3532           if (need_redo) {
    3533             kv_concat_len(redobuff.cur.keys, start, (size_t)(s - start));
    3534           }
    3535           if (need_record) {
    >>>     CID 653189:           (OVERRUN)
    >>>     Overrunning dynamic array "recordbuff.items" at offset corresponding to index variable "recordbuff.size" through dereference in call to "memcpy".
    3536             kv_concat_len(recordbuff, start, (size_t)(s - start));
    3537           }
    3538         }
    3539
    3540         if (s < str_end) {
    3541           int c = (uint8_t)(*s++);

    _____________________________________________________________________________________________
    CID 653188:         Memory - illegal accesses  (OVERRUN)
    /src/nvim/input_cmdatom.c: 216             in atoms_concat_keys()
    210
    211     /// Concatenates the keys of multiple atoms into one (allocated) string.
    212     static String atoms_concat_keys(CmdAtomVec atoms)
    213     {
    214       StringBuilder keys = KV_INITIAL_VALUE;
    215       for (size_t i = 0; i < kv_size(atoms); i++) {
    >>>     CID 653188:         Memory - illegal accesses  (OVERRUN)
    >>>     Overrunning dynamic array "keys.items" at offset corresponding to index variable "keys.size" through dereference in call to "memcpy".
    216         kv_concat(keys, kv_A(atoms, i).keys);
    217       }
    218       size_t len = kv_size(keys);
    219       kv_push(keys, NUL);
    220       return (String){ .data = keys.items, .size = len };
    221     }

    CID 653187:       Null pointer dereferences  (FORWARD_NULL)

    _____________________________________________________________________________________________
    CID 653186:         Null pointer dereferences  (FORWARD_NULL)
    /src/nvim/input_cmdatom.c: 173             in atom_compose_keys()
    167       StringBuilder sb = KV_INITIAL_VALUE;
    168       redo_prefix(&spec, &sb, false);
    169       redo_chars(&spec, &sb, false);
    170       if (sb.size == 0) {
    171         return NULL;
    172       }
    >>>     CID 653186:         Null pointer dereferences  (FORWARD_NULL)
    >>>     Dereferencing null pointer "((sb.size == sb.capacity) ? (sb.capacity = (sb.capacity ? sb.capacity << 1 : 8UL)) , (sb.items = xrealloc(sb.items, 1UL * sb.capacity)) , 0 : 0) , (sb.items + sb.size++)".
    173       kv_push(sb, NUL);
    174       return sb.items;
    175     }
    176
    177     /// The pending change as a CmdAtom: the composed keysequence plus the structured fields.
    178     /// Caller owns `keys`.

    _____________________________________________________________________________________________
    CID 653185:         Null pointer dereferences  (FORWARD_NULL)
    /src/nvim/input.c: 296             in redo_compose()
    290       StringBuilder buf = KV_INITIAL_VALUE;
    291       redo_prefix(&r->spec, &buf, false);
    292       kv_splice(buf, r->keys);
    293       if (buf.size == 0) {
    294         return (String)STRING_INIT;
    295       }
    >>>     CID 653185:         Null pointer dereferences  (FORWARD_NULL)
    >>>     Dereferencing null pointer "((buf.size == buf.capacity) ? (buf.capacity = (buf.capacity ? buf.capacity << 1 : 8UL)) , (buf.items = xrealloc(buf.items, 1UL * buf.capacity)) , 0 : 0) , (buf.items + buf.size++)".
    296       kv_push(buf, NUL);
    297       return cbuf_as_string(buf.items, buf.size - 1);
    298     }
    299
    301     String redo_keys(void)

    _____________________________________________________________________________________________
    CID 653184:         Memory - illegal accesses  (OVERRUN)
    /src/nvim/input.c: 3533             in paste_store()
    3527                && *s != NL && !(crlf && *s == CAR)) {
    3528           s++;
    3529         }
    3530
    3531         if (s > start) {
    3532           if (need_redo) {
    >>>     CID 653184:         Memory - illegal accesses  (OVERRUN)
    >>>     Overrunning dynamic array "redobuff.cur.keys.items" at offset corresponding to index variable "redobuff.cur.keys.size" through dereference in call to "memcpy".
    3533             kv_concat_len(redobuff.cur.keys, start, (size_t)(s - start));
    3534           }
    3535           if (need_record) {
    3536             kv_concat_len(recordbuff, start, (size_t)(s - start));
    3537           }
    3538         }

    _____________________________________________________________________________________________
    CID 653183:         Memory - illegal accesses  (OVERRUN)
    /src/nvim/input.c: 730             in redo_append_spec()
    724         return;
    725       }
    726
    727       while (*s != NUL) {
    728         if ((uint8_t)(*s) == K_SPECIAL && s[1] != NUL && s[2] != NUL) {
    729           // Insert special key literally.
    >>>     CID 653183:         Memory - illegal accesses  (OVERRUN)
    >>>     Overrunning dynamic array "redobuff.cur.keys.items" at offset corresponding to index variable "redobuff.cur.keys.size" through dereference in call to "memcpy".
    730           kv_concat_len(redobuff.cur.keys, s, 3);
    731           s += 3;
    732         } else {
    733           sb_add_char(&redobuff.cur.keys, mb_cptr2char_adv(&s));
    734         }
2026-08-16 11:37:51 -04:00
2025-12-30 01:44:52 -05:00
2026-03-13 12:29:44 +00:00
2025-01-11 10:34:12 +01:00
2026-04-18 15:38:59 -04:00
2026-03-11 18:00:18 +01:00
2026-04-16 10:48:11 -04:00

Neovim

Documentation | Chat

Coverity Scan analysis Packages Debian CI Downloads

Neovim is a project that seeks to aggressively refactor Vim in order to:

See the Introduction wiki page and Roadmap for more information.

Features

See :help nvim-features for the full list, and :help news for noteworthy changes in the latest version!

Install from package

Pre-built packages for Windows, macOS, and Linux are found on the Releases page.

Managed packages are in Homebrew, Debian, Ubuntu, Fedora, Arch Linux, Void Linux, Gentoo, and more!

Install from source

See BUILD.md and supported platforms for details.

The build is CMake-based, but a Makefile is provided as a convenience. After installing the dependencies, run the following command.

make CMAKE_BUILD_TYPE=RelWithDebInfo
sudo make install

To install to a non-default location:

make CMAKE_BUILD_TYPE=RelWithDebInfo CMAKE_INSTALL_PREFIX=/full/path/
make install

CMake hints for inspecting the build:

  • cmake --build build --target help lists all build targets.
  • build/CMakeCache.txt (or cmake -LAH build/) contains the resolved values of all CMake variables.
  • build/compile_commands.json shows the full compiler invocations for each translation unit.

Transitioning from Vim

See :help nvim-from-vim for instructions.

Project layout

├─ cmake/           CMake utils
├─ cmake.config/    CMake defines
├─ cmake.deps/      subproject to fetch and build dependencies (optional)
├─ runtime/         plugins and docs
├─ src/nvim/        application source code (see src/nvim/README.md)
│  ├─ api/          API subsystem
│  ├─ eval/         Vimscript subsystem
│  ├─ event/        event-loop subsystem
│  ├─ generators/   code generation (pre-compilation)
│  ├─ lib/          generic data structures
│  ├─ lua/          Lua subsystem
│  ├─ msgpack_rpc/  RPC subsystem
│  ├─ os/           low-level platform code
│  └─ tui/          built-in UI
└─ test/            tests (see test/README.md)

License

Neovim contributions since b17d96 are licensed under the Apache 2.0 license, except for contributions copied from Vim (identified by the vim-patch token). See LICENSE.txt for details.

Description
Vim-fork focused on extensibility and usability
Readme 509 MiB
Languages
Vim Script 39.7%
Lua 32.6%
C 26.7%
CMake 0.4%
Zig 0.2%
Other 0.1%