clang/"null pointer dereference" #10776

assert(curbuf) in ins_compl_get_exp
This commit is contained in:
Ihor Antonov
2019-08-14 14:50:30 -04:00
committed by Justin M. Keyes
parent 5cc45bb419
commit ebcb9adcc4

View File

@@ -3842,23 +3842,21 @@ int ins_compl_add_tv(typval_T *const tv, const Direction dir)
(char_u **)cptext, true, dir, 0, adup, aequal); (char_u **)cptext, true, dir, 0, adup, aequal);
} }
/* // Get the next expansion(s), using "compl_pattern".
* Get the next expansion(s), using "compl_pattern". // The search starts at position "ini" in curbuf and in the direction
* The search starts at position "ini" in curbuf and in the direction // compl_direction.
* compl_direction. // When "compl_started" is FALSE start at that position, otherwise continue
* When "compl_started" is FALSE start at that position, otherwise continue // where we stopped searching before.
* where we stopped searching before. // This may return before finding all the matches.
* This may return before finding all the matches. // Return the total number of matches or -1 if still unknown -- Acevedo
* Return the total number of matches or -1 if still unknown -- Acevedo
*/
static int ins_compl_get_exp(pos_T *ini) static int ins_compl_get_exp(pos_T *ini)
{ {
static pos_T first_match_pos; static pos_T first_match_pos;
static pos_T last_match_pos; static pos_T last_match_pos;
static char_u *e_cpt = (char_u *)""; /* curr. entry in 'complete' */ static char_u *e_cpt = (char_u *)""; // curr. entry in 'complete'
static int found_all = FALSE; /* Found all matches of a static int found_all = false; // Found all matches of a
certain type. */ // certain type.
static buf_T *ins_buf = NULL; /* buffer being scanned */ static buf_T *ins_buf = NULL; // buffer being scanned
pos_T *pos; pos_T *pos;
char_u **matches; char_u **matches;
@@ -3876,6 +3874,8 @@ static int ins_compl_get_exp(pos_T *ini)
int set_match_pos; int set_match_pos;
int l_ctrl_x_mode = ctrl_x_mode; int l_ctrl_x_mode = ctrl_x_mode;
assert(curbuf != NULL);
if (!compl_started) { if (!compl_started) {
FOR_ALL_BUFFERS(buf) { FOR_ALL_BUFFERS(buf) {
buf->b_scanned = false; buf->b_scanned = false;
@@ -3899,9 +3899,9 @@ static int ins_compl_get_exp(pos_T *ini)
assert(l_ctrl_x_mode == ctrl_x_mode); assert(l_ctrl_x_mode == ctrl_x_mode);
/* For ^N/^P pick a new entry from e_cpt if compl_started is off, // For ^N/^P pick a new entry from e_cpt if compl_started is off,
* or if found_all says this entry is done. For ^X^L only use the // or if found_all says this entry is done. For ^X^L only use the
* entries from 'complete' that look in loaded buffers. */ // entries from 'complete' that look in loaded buffers.
if ((l_ctrl_x_mode == CTRL_X_NORMAL if ((l_ctrl_x_mode == CTRL_X_NORMAL
|| CTRL_X_MODE_LINE_OR_EVAL(l_ctrl_x_mode)) || CTRL_X_MODE_LINE_OR_EVAL(l_ctrl_x_mode))
&& (!compl_started || found_all)) { && (!compl_started || found_all)) {
@@ -3923,23 +3923,24 @@ static int ins_compl_get_exp(pos_T *ini)
last_match_pos = first_match_pos; last_match_pos = first_match_pos;
type = 0; type = 0;
/* Remember the first match so that the loop stops when we // Remember the first match so that the loop stops when we
* wrap and come back there a second time. */ // wrap and come back there a second time.
set_match_pos = TRUE; set_match_pos = true;
} else if (vim_strchr((char_u *)"buwU", *e_cpt) != NULL } else if (vim_strchr((char_u *)"buwU", *e_cpt) != NULL
&& (ins_buf = && (ins_buf =
ins_compl_next_buf(ins_buf, *e_cpt)) != curbuf) { ins_compl_next_buf(ins_buf, *e_cpt)) != curbuf) {
/* Scan a buffer, but not the current one. */ // Scan a buffer, but not the current one.
if (ins_buf->b_ml.ml_mfp != NULL) { /* loaded buffer */ if (ins_buf->b_ml.ml_mfp != NULL) { // loaded buffer
compl_started = TRUE; compl_started = true;
first_match_pos.col = last_match_pos.col = 0; first_match_pos.col = last_match_pos.col = 0;
first_match_pos.lnum = ins_buf->b_ml.ml_line_count + 1; first_match_pos.lnum = ins_buf->b_ml.ml_line_count + 1;
last_match_pos.lnum = 0; last_match_pos.lnum = 0;
type = 0; type = 0;
} else { /* unloaded buffer, scan like dictionary */ } else { // unloaded buffer, scan like dictionary
found_all = TRUE; found_all = true;
if (ins_buf->b_fname == NULL) if (ins_buf->b_fname == NULL) {
continue; continue;
}
type = CTRL_X_DICTIONARY; type = CTRL_X_DICTIONARY;
dict = ins_buf->b_fname; dict = ins_buf->b_fname;
dict_f = DICT_EXACT; dict_f = DICT_EXACT;
@@ -3977,7 +3978,7 @@ static int ins_compl_get_exp(pos_T *ini)
type = -1; type = -1;
} }
/* in any case e_cpt is advanced to the next entry */ // in any case e_cpt is advanced to the next entry
(void)copy_option_part(&e_cpt, IObuff, IOSIZE, ","); (void)copy_option_part(&e_cpt, IObuff, IOSIZE, ",");
found_all = TRUE; found_all = TRUE;
@@ -4024,12 +4025,12 @@ static int ins_compl_get_exp(pos_T *ini)
break; break;
case CTRL_X_TAGS: case CTRL_X_TAGS:
/* set p_ic according to p_ic, p_scs and pat for find_tags(). */ // set p_ic according to p_ic, p_scs and pat for find_tags().
save_p_ic = p_ic; save_p_ic = p_ic;
p_ic = ignorecase(compl_pattern); p_ic = ignorecase(compl_pattern);
/* Find up to TAG_MANY matches. Avoids that an enormous number // Find up to TAG_MANY matches. Avoids that an enormous number
* of matches is found when compl_pattern is empty */ // of matches is found when compl_pattern is empty
if (find_tags(compl_pattern, &num_matches, &matches, if (find_tags(compl_pattern, &num_matches, &matches,
TAG_REGEXP | TAG_NAMES | TAG_NOIC | TAG_INS_COMP TAG_REGEXP | TAG_NAMES | TAG_NOIC | TAG_INS_COMP
| (l_ctrl_x_mode != CTRL_X_NORMAL ? TAG_VERBOSE : 0), | (l_ctrl_x_mode != CTRL_X_NORMAL ? TAG_VERBOSE : 0),
@@ -4042,8 +4043,7 @@ static int ins_compl_get_exp(pos_T *ini)
case CTRL_X_FILES: case CTRL_X_FILES:
if (expand_wildcards(1, &compl_pattern, &num_matches, &matches, if (expand_wildcards(1, &compl_pattern, &num_matches, &matches,
EW_FILE|EW_DIR|EW_ADDSLASH|EW_SILENT) == OK) { EW_FILE|EW_DIR|EW_ADDSLASH|EW_SILENT) == OK) {
// May change home directory back to "~".
/* May change home directory back to "~". */
tilde_replace(compl_pattern, num_matches, matches); tilde_replace(compl_pattern, num_matches, matches);
ins_compl_add_matches(num_matches, matches, p_fic || p_wic); ins_compl_add_matches(num_matches, matches, p_fic || p_wic);
} }
@@ -4068,19 +4068,17 @@ static int ins_compl_get_exp(pos_T *ini)
ins_compl_add_matches(num_matches, matches, p_ic); ins_compl_add_matches(num_matches, matches, p_ic);
break; break;
default: /* normal ^P/^N and ^X^L */ default: // normal ^P/^N and ^X^L
/* // If 'infercase' is set, don't use 'smartcase' here
* If 'infercase' is set, don't use 'smartcase' here
*/
save_p_scs = p_scs; save_p_scs = p_scs;
assert(ins_buf); assert(ins_buf);
if (ins_buf->b_p_inf) if (ins_buf->b_p_inf)
p_scs = FALSE; p_scs = FALSE;
/* Buffers other than curbuf are scanned from the beginning or the // Buffers other than curbuf are scanned from the beginning or the
* end but never from the middle, thus setting nowrapscan in this // end but never from the middle, thus setting nowrapscan in this
* buffers is a good idea, on the other hand, we always set // buffers is a good idea, on the other hand, we always set
* wrapscan for curbuf to avoid missing matches -- Acevedo,Webb */ // wrapscan for curbuf to avoid missing matches -- Acevedo,Webb
save_p_ws = p_ws; save_p_ws = p_ws;
if (ins_buf != curbuf) if (ins_buf != curbuf)
p_ws = false; p_ws = false;
@@ -4089,8 +4087,7 @@ static int ins_compl_get_exp(pos_T *ini)
for (;; ) { for (;; ) {
int flags = 0; int flags = 0;
++msg_silent; /* Don't want messages for wrapscan. */ msg_silent++; // Don't want messages for wrapscan.
// CTRL_X_MODE_LINE_OR_EVAL(l_ctrl_x_mode) || word-wise search that // CTRL_X_MODE_LINE_OR_EVAL(l_ctrl_x_mode) || word-wise search that
// has added a word that was at the beginning of the line. // has added a word that was at the beginning of the line.
if (CTRL_X_MODE_LINE_OR_EVAL(l_ctrl_x_mode) if (CTRL_X_MODE_LINE_OR_EVAL(l_ctrl_x_mode)
@@ -4107,47 +4104,52 @@ static int ins_compl_get_exp(pos_T *ini)
} }
msg_silent--; msg_silent--;
if (!compl_started || set_match_pos) { if (!compl_started || set_match_pos) {
/* set "compl_started" even on fail */ // set "compl_started" even on fail
compl_started = TRUE; compl_started = true;
first_match_pos = *pos; first_match_pos = *pos;
last_match_pos = *pos; last_match_pos = *pos;
set_match_pos = FALSE; set_match_pos = false;
} else if (first_match_pos.lnum == last_match_pos.lnum } else if (first_match_pos.lnum == last_match_pos.lnum
&& first_match_pos.col == last_match_pos.col) && first_match_pos.col == last_match_pos.col) {
found_new_match = FAIL; found_new_match = FAIL;
}
if (found_new_match == FAIL) { if (found_new_match == FAIL) {
if (ins_buf == curbuf) if (ins_buf == curbuf)
found_all = TRUE; found_all = TRUE;
break; break;
} }
/* when ADDING, the text before the cursor matches, skip it */ // when ADDING, the text before the cursor matches, skip it
if ( (compl_cont_status & CONT_ADDING) && ins_buf == curbuf if ((compl_cont_status & CONT_ADDING) && ins_buf == curbuf
&& ini->lnum == pos->lnum && ini->lnum == pos->lnum
&& ini->col == pos->col) && ini->col == pos->col) {
continue; continue;
ptr = ml_get_buf(ins_buf, pos->lnum, FALSE) + pos->col; }
ptr = ml_get_buf(ins_buf, pos->lnum, false) + pos->col;
if (CTRL_X_MODE_LINE_OR_EVAL(l_ctrl_x_mode)) { if (CTRL_X_MODE_LINE_OR_EVAL(l_ctrl_x_mode)) {
if (compl_cont_status & CONT_ADDING) { if (compl_cont_status & CONT_ADDING) {
if (pos->lnum >= ins_buf->b_ml.ml_line_count) if (pos->lnum >= ins_buf->b_ml.ml_line_count) {
continue; continue;
ptr = ml_get_buf(ins_buf, pos->lnum + 1, FALSE); }
if (!p_paste) ptr = ml_get_buf(ins_buf, pos->lnum + 1, false);
if (!p_paste) {
ptr = skipwhite(ptr); ptr = skipwhite(ptr);
} }
}
len = (int)STRLEN(ptr); len = (int)STRLEN(ptr);
} else { } else {
char_u *tmp_ptr = ptr; char_u *tmp_ptr = ptr;
if (compl_cont_status & CONT_ADDING) { if (compl_cont_status & CONT_ADDING) {
tmp_ptr += compl_length; tmp_ptr += compl_length;
/* Skip if already inside a word. */ // Skip if already inside a word.
if (vim_iswordp(tmp_ptr)) if (vim_iswordp(tmp_ptr)) {
continue; continue;
/* Find start of next word. */ }
// Find start of next word.
tmp_ptr = find_word_start(tmp_ptr); tmp_ptr = find_word_start(tmp_ptr);
} }
/* Find end of this word. */ // Find end of this word.
tmp_ptr = find_word_end(tmp_ptr); tmp_ptr = find_word_end(tmp_ptr);
len = (int)(tmp_ptr - ptr); len = (int)(tmp_ptr - ptr);
@@ -4160,15 +4162,16 @@ static int ins_compl_get_exp(pos_T *ini)
STRNCPY(IObuff, ptr, len); STRNCPY(IObuff, ptr, len);
ptr = ml_get_buf(ins_buf, pos->lnum + 1, false); ptr = ml_get_buf(ins_buf, pos->lnum + 1, false);
tmp_ptr = ptr = skipwhite(ptr); tmp_ptr = ptr = skipwhite(ptr);
/* Find start of next word. */ // Find start of next word.
tmp_ptr = find_word_start(tmp_ptr); tmp_ptr = find_word_start(tmp_ptr);
/* Find end of next word. */ // Find end of next word.
tmp_ptr = find_word_end(tmp_ptr); tmp_ptr = find_word_end(tmp_ptr);
if (tmp_ptr > ptr) { if (tmp_ptr > ptr) {
if (*ptr != ')' && IObuff[len - 1] != TAB) { if (*ptr != ')' && IObuff[len - 1] != TAB) {
if (IObuff[len - 1] != ' ') if (IObuff[len - 1] != ' ') {
IObuff[len++] = ' '; IObuff[len++] = ' ';
/* IObuf =~ "\k.* ", thus len >= 2 */ }
// IObuf =~ "\k.* ", thus len >= 2
if (p_js if (p_js
&& (IObuff[len - 2] == '.' && (IObuff[len - 2] == '.'
|| IObuff[len - 2] == '?' || IObuff[len - 2] == '?'
@@ -4176,9 +4179,10 @@ static int ins_compl_get_exp(pos_T *ini)
IObuff[len++] = ' '; IObuff[len++] = ' ';
} }
} }
/* copy as much as possible of the new word */ // copy as much as possible of the new word
if (tmp_ptr - ptr >= IOSIZE - len) if (tmp_ptr - ptr >= IOSIZE - len) {
tmp_ptr = ptr + IOSIZE - len - 1; tmp_ptr = ptr + IOSIZE - len - 1;
}
STRNCPY(IObuff + len, ptr, tmp_ptr - ptr); STRNCPY(IObuff + len, ptr, tmp_ptr - ptr);
len += (int)(tmp_ptr - ptr); len += (int)(tmp_ptr - ptr);
flags |= CONT_S_IPOS; flags |= CONT_S_IPOS;
@@ -4214,9 +4218,10 @@ static int ins_compl_get_exp(pos_T *ini)
|| found_new_match != FAIL) { || found_new_match != FAIL) {
if (got_int) if (got_int)
break; break;
/* Fill the popup menu as soon as possible. */ // Fill the popup menu as soon as possible.
if (type != -1) if (type != -1) {
ins_compl_check_keys(0, false); ins_compl_check_keys(0, false);
}
if ((l_ctrl_x_mode != CTRL_X_NORMAL if ((l_ctrl_x_mode != CTRL_X_NORMAL
&& !CTRL_X_MODE_LINE_OR_EVAL(l_ctrl_x_mode)) && !CTRL_X_MODE_LINE_OR_EVAL(l_ctrl_x_mode))
@@ -4225,7 +4230,7 @@ static int ins_compl_get_exp(pos_T *ini)
} }
compl_started = TRUE; compl_started = TRUE;
} else { } else {
/* Mark a buffer scanned when it has been scanned completely */ // Mark a buffer scanned when it has been scanned completely
if (type == 0 || type == CTRL_X_PATH_PATTERNS) { if (type == 0 || type == CTRL_X_PATH_PATTERNS) {
assert(ins_buf); assert(ins_buf);
ins_buf->b_scanned = true; ins_buf->b_scanned = true;
@@ -4242,7 +4247,7 @@ static int ins_compl_get_exp(pos_T *ini)
found_new_match = FAIL; found_new_match = FAIL;
} }
i = -1; /* total of matches, unknown */ i = -1; // total of matches, unknown
if (found_new_match == FAIL if (found_new_match == FAIL
|| (l_ctrl_x_mode != CTRL_X_NORMAL || (l_ctrl_x_mode != CTRL_X_NORMAL
&& !CTRL_X_MODE_LINE_OR_EVAL(l_ctrl_x_mode))) { && !CTRL_X_MODE_LINE_OR_EVAL(l_ctrl_x_mode))) {
@@ -4263,7 +4268,7 @@ static int ins_compl_get_exp(pos_T *ini)
return i; return i;
} }
/* Delete the old text being completed. */ // Delete the old text being completed.
static void ins_compl_delete(void) static void ins_compl_delete(void)
{ {
int col; int col;