From ba0ee081c8746a148bfad1420919fa04dfb0b67a Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Thu, 3 Sep 2026 12:41:40 -0400 Subject: [PATCH] fix(coverity): DEADCODE, FORWARD_NULL, UNINIT #41667 Problem: CID 655469: (DEADCODE) /build/src/nvim/auto/lua_api_c_bindings.generated.h: 7696 in nlua_api_nvim__mcursor_cascading() 7690 7691 exit_0: 7692 arena_mem_free(arena_finish(&arena)); 7693 if (ERROR_SET(&err)) { 7694 luaL_where(lstate, 1); 7695 if (err_param) { >>> CID 655469: (DEADCODE) >>> Execution cannot reach this statement: "lua_pushstring(lstate, "Inv...". 7696 lua_pushstring(lstate, "Invalid '"); 7697 lua_pushstring(lstate, err_param); 7698 lua_pushstring(lstate, "': "); 7699 } 7700 lua_pushstring(lstate, err.msg); 7701 api_clear_error(&err); /build/src/nvim/auto/lua_api_c_bindings.generated.h: 7702 in nlua_api_nvim__mcursor_cascading() 7696 lua_pushstring(lstate, "Invalid '"); 7697 lua_pushstring(lstate, err_param); 7698 lua_pushstring(lstate, "': "); 7699 } 7700 lua_pushstring(lstate, err.msg); 7701 api_clear_error(&err); >>> CID 655469: (DEADCODE) >>> Execution cannot reach the expression "5" inside this statement: "lua_concat(lstate, (err_par...". 7702 lua_concat(lstate, err_param ? 5 : 2); 7703 return lua_error(lstate); 7704 } 7705 7706 return 1; 7707 } CID 655468: Null pointer dereferences (FORWARD_NULL) /src/nvim/mcursor.c: 833 in mc_ins_cascade() 827 mc_ins_span_push(keys.items, NULL); 828 mc_ins_preview_rebase(); 829 } 830 } else if (ins.data != NULL && ins.size < mc_ins_span.done_len) { 831 // Capture shrank without a restart signal, e.g. completion surgery rewrote the pending keys. 832 mc_ins_cascade_restart(); >>> CID 655468: Null pointer dereferences (FORWARD_NULL) >>> Passing null pointer "ins.data + mc_ins_span.done_len" to "mc_ins_keys_nonliteral", which dereferences it. 833 } else if (ins.size > mc_ins_span.done_len 834 && mc_ins_keys_nonliteral(ins.data + mc_ins_span.done_len, 835 ins.size - mc_ins_span.done_len)) { 836 // Non-literal keys pending (BS, CTRL-U, ...): re-execute instead of previewing. 837 mc_ins_span_flush(&ins, false); 838 } else { CID 655467: Uninitialized variables (UNINIT) /src/nvim/mcursor.c: 1041 in mc_vsel_refresh() 1035 for (size_t i = 0; i < kv_size(mc_cursors); i++) { 1036 Context *ctx = &kv_A(mc_cursors, i); 1037 pos_T pos; 1038 if (!mc_ctx_resolve(ctx, &pos)) { 1039 continue; 1040 } >>> CID 655467: Uninitialized variables (UNINIT) >>> Using uninitialized value "pos". Field "pos.coladd" is uninitialized. 1041 curwin->w_cursor = pos; 1042 check_cursor(curwin); 1044 Visual.select = false; 1045 nvim_feedkeys(span, cstr_as_string("nix"), false); 1046 if (!Visual.active) { Solution: - CID 655467 UNINIT: real (minor). `mc_vsel_refresh()` copied uninitialized local into `curwin->w_cursor`, and garbage coladd survived into the Visual replay (`equalpos()` compares it). - Fix: `pos_T pos = { 0 }` - CID 655468 FORWARD_NULL: false positive - CID 655469 DEADCODE: generated code. `nvim__mcursor_cascading` is flagged bc it is new, - TODO: teach `gen_api_dispatch.lua` to omit the branch for parameterless functions. --- src/nvim/mcursor.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/nvim/mcursor.c b/src/nvim/mcursor.c index 54774167b7..2c58f14045 100644 --- a/src/nvim/mcursor.c +++ b/src/nvim/mcursor.c @@ -694,7 +694,7 @@ static void mc_ins_preview_rebase(void) mc_ins_regions_clear(); for (size_t i = 0; i < kv_size(mc_cursors); i++) { Context *ctx = &kv_A(mc_cursors, i); - pos_T pos; + pos_T pos = { 0 }; uint32_t mark = 0; if (mc_ctx_resolve(ctx, &pos)) { mc_region_mark_set(&mark, pos); @@ -822,6 +822,7 @@ void mc_ins_cascade(void) return; } String ins = redo_keys(NULL); + assert(ins.data != NULL || ins.size == 0); // Coverity: NULL only when empty. if (mc_ins_span.first) { // Not with a pending autoindent ("o" + 'autoindent'): the entry span's replay ends in , // which would delete the indent. @@ -1045,7 +1046,7 @@ void mc_vsel_refresh(void) for (size_t i = 0; i < kv_size(mc_cursors); i++) { Context *ctx = &kv_A(mc_cursors, i); - pos_T pos; + pos_T pos = { 0 }; if (!mc_ctx_resolve(ctx, &pos)) { continue; }