aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/tokenizer.cpp
diff options
context:
space:
mode:
authorGravatar ridiculousfish <corydoras@ridiculousfish.com>2015-10-07 11:38:13 -0700
committerGravatar ridiculousfish <corydoras@ridiculousfish.com>2015-10-07 11:38:13 -0700
commite8605cb3ef1b7329c15daa039f0cd3eae35da48c (patch)
tree6afefc0512bb15dddc9a089a058494cb58dcb535 /src/tokenizer.cpp
parent1bdf06836ac6075ec1728a77050447c980b6f8a1 (diff)
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!
Diffstat (limited to 'src/tokenizer.cpp')
-rw-r--r--src/tokenizer.cpp42
1 files changed, 23 insertions, 19 deletions
diff --git a/src/tokenizer.cpp b/src/tokenizer.cpp
index b50673ea..0354235a 100644
--- a/src/tokenizer.cpp
+++ b/src/tokenizer.cpp
@@ -466,31 +466,33 @@ static size_t read_redirection_or_fd_pipe(const wchar_t *buff, enum token_type *
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 */
if (errored)
{
idx = 0;
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 */
if (out_redirection_mode != NULL)
@@ -684,7 +686,9 @@ void tokenizer_t::tok_next()
enum token_type mode = TOK_NONE;
int fd = -1;
if (iswdigit(*this->buff))
+ {
consumed = read_redirection_or_fd_pipe(this->buff, &mode, &fd);
+ }
if (consumed > 0)
{