Use vim_strchr(s, c) when c may be NUL (#6656)

As part of the refactoring in #5119, some vim_strchr() were changed to
strchr().  However, vim_strchr() behaves differently than strchr() when
c is NUL, returning NULL instead of a pointer to the NUL.

Revert the strchr() calls where it isn't known whether c is NUL, since
this causes a semantic change the surrounding code doesn't expect.  In
the case of #6650, this led to a heap overrun.

Closes #6650
This commit is contained in:
James McCoy 2017-05-03 04:12:38 -04:00 committed by Justin M. Keyes
parent 08b23d0806
commit de50c003d5
4 changed files with 27 additions and 5 deletions

View File

@ -2687,7 +2687,7 @@ const char * set_one_cmd_context(
// 2. skip comment lines and leading space, colons or bars // 2. skip comment lines and leading space, colons or bars
const char *cmd; const char *cmd;
for (cmd = buff; strchr(" \t:|", *cmd) != NULL; cmd++) { for (cmd = buff; vim_strchr((const char_u *)" \t:|", *cmd) != NULL; cmd++) {
} }
xp->xp_pattern = (char_u *)cmd; xp->xp_pattern = (char_u *)cmd;
@ -2748,7 +2748,7 @@ const char * set_one_cmd_context(
} }
} }
// check for non-alpha command // check for non-alpha command
if (p == cmd && strchr("@*!=><&~#", *p) != NULL) { if (p == cmd && vim_strchr((const char_u *)"@*!=><&~#", *p) != NULL) {
p++; p++;
} }
len = (size_t)(p - cmd); len = (size_t)(p - cmd);
@ -2779,7 +2779,7 @@ const char * set_one_cmd_context(
return NULL; return NULL;
if (ea.cmdidx == CMD_SIZE) { if (ea.cmdidx == CMD_SIZE) {
if (*cmd == 's' && strchr("cgriI", cmd[1]) != NULL) { if (*cmd == 's' && vim_strchr((const char_u *)"cgriI", cmd[1]) != NULL) {
ea.cmdidx = CMD_substitute; ea.cmdidx = CMD_substitute;
p = cmd + 1; p = cmd + 1;
} else if (cmd[0] >= 'A' && cmd[0] <= 'Z') { } else if (cmd[0] >= 'A' && cmd[0] <= 'Z') {

View File

@ -584,7 +584,7 @@ static int command_line_execute(VimState *state, int key)
} }
if (vim_ispathsep(ccline.cmdbuff[s->j]) if (vim_ispathsep(ccline.cmdbuff[s->j])
#ifdef BACKSLASH_IN_FILENAME #ifdef BACKSLASH_IN_FILENAME
&& strchr(" *?[{`$%#", ccline.cmdbuff[s->j + 1]) && vim_strchr(" *?[{`$%#", ccline.cmdbuff[s->j + 1])
== NULL == NULL
#endif #endif
) { ) {

View File

@ -1411,7 +1411,8 @@ do_set (
errmsg = (char_u *)set_bool_option(opt_idx, varp, (int)value, errmsg = (char_u *)set_bool_option(opt_idx, varp, (int)value,
opt_flags); opt_flags);
} else { // Numeric or string. } else { // Numeric or string.
if (strchr("=:&<", nextchar) == NULL || prefix != 1) { if (vim_strchr((const char_u *)"=:&<", nextchar) == NULL
|| prefix != 1) {
errmsg = e_invarg; errmsg = e_invarg;
goto skip; goto skip;
} }

View File

@ -31,6 +31,27 @@ describe("'wildmode'", function()
:sign define^ | :sign define^ |
]]) ]])
end) end)
it('does not crash after cycling back to original text', function()
command('set wildmode=full')
feed(':j<Tab><Tab><Tab>')
screen:expect([[
|
~ |
~ |
join jumps |
:j^ |
]])
-- This would cause nvim to crash before #6650
feed('<BS><Tab>')
screen:expect([[
|
~ |
~ |
! # & < = > @ > |
:!^ |
]])
end)
end) end)
end) end)