Fix a dereference-past-the-end bug in read_redirection_or_fd_pipe

Fixes #2464. Credit to zanchey for reporting it and ASAN for finding it!
This commit is contained in:
ridiculousfish
2015-10-07 11:38:13 -07:00
parent 1bdf06836a
commit e8605cb3ef

View File

@@ -466,31 +466,33 @@ static size_t read_redirection_or_fd_pipe(const wchar_t *buff, enum token_type *
errored = true; errored = true;
} }
/* Optional characters like & or ?, or the pipe char | */
wchar_t opt_char = buff[idx];
if (opt_char == L'&')
{
redirection_mode = TOK_REDIRECT_FD;
idx++;
}
else if (opt_char == L'?')
{
redirection_mode = TOK_REDIRECT_NOCLOB;
idx++;
}
else if (opt_char == L'|')
{
/* So the string looked like '2>|'. This is not a redirection - it's a pipe! That gets handled elsewhere. */
redirection_mode = TOK_PIPE;
idx++;
}
/* Don't return valid-looking stuff on error */ /* Don't return valid-looking stuff on error */
if (errored) if (errored)
{ {
idx = 0; idx = 0;
redirection_mode = TOK_NONE; redirection_mode = TOK_NONE;
} }
else
{
/* Optional characters like & or ?, or the pipe char | */
wchar_t opt_char = buff[idx];
if (opt_char == L'&')
{
redirection_mode = TOK_REDIRECT_FD;
idx++;
}
else if (opt_char == L'?')
{
redirection_mode = TOK_REDIRECT_NOCLOB;
idx++;
}
else if (opt_char == L'|')
{
/* So the string looked like '2>|'. This is not a redirection - it's a pipe! That gets handled elsewhere. */
redirection_mode = TOK_PIPE;
idx++;
}
}
/* Return stuff */ /* Return stuff */
if (out_redirection_mode != NULL) if (out_redirection_mode != NULL)
@@ -684,7 +686,9 @@ void tokenizer_t::tok_next()
enum token_type mode = TOK_NONE; enum token_type mode = TOK_NONE;
int fd = -1; int fd = -1;
if (iswdigit(*this->buff)) if (iswdigit(*this->buff))
{
consumed = read_redirection_or_fd_pipe(this->buff, &mode, &fd); consumed = read_redirection_or_fd_pipe(this->buff, &mode, &fd);
}
if (consumed > 0) if (consumed > 0)
{ {