mirror of
https://github.com/neovim/neovim.git
synced 2026-08-28 01:51:52 +00:00
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 }
This commit is contained in:
@@ -108,6 +108,8 @@
|
||||
if (len > 0) { \
|
||||
kv_ensure_space(v, len); \
|
||||
assert((v).items); \
|
||||
/* kv_roundup32() only ORs bits in, so kv_ensure_space() leaves capacity >= size+len. */ \
|
||||
/* coverity[overrun-buffer-arg] */ \
|
||||
memcpy((v).items + (v).size, data, sizeof((v).items[0]) * len); \
|
||||
(v).size = (v).size + len; \
|
||||
}
|
||||
|
||||
@@ -293,6 +293,7 @@ static String redo_compose(RedoBuf *r)
|
||||
if (buf.size == 0) {
|
||||
return (String)STRING_INIT;
|
||||
}
|
||||
assert(buf.items != NULL); // Coverity false-positive (already checked `size` above).
|
||||
kv_push(buf, NUL);
|
||||
return cbuf_as_string(buf.items, buf.size - 1);
|
||||
}
|
||||
@@ -865,6 +866,7 @@ int start_redo(int count, bool old_redo)
|
||||
}
|
||||
StringBuilder prefix = KV_INITIAL_VALUE;
|
||||
redo_prefix(&spec, &prefix, true);
|
||||
// coverity[var_deref_model] `items` is NULL only when size=0, which add_buff() ignores.
|
||||
add_buff(&readbuf2, prefix.items, (ptrdiff_t)prefix.size);
|
||||
kv_destroy(prefix);
|
||||
if (spec.regname == '=') {
|
||||
|
||||
@@ -170,6 +170,7 @@ static char *atom_compose_keys(CmdSpec spec)
|
||||
if (sb.size == 0) {
|
||||
return NULL;
|
||||
}
|
||||
assert(sb.items != NULL); // Coverity false-positive (already checked `size` above).
|
||||
kv_push(sb, NUL);
|
||||
return sb.items;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user