diff options
author | Cary Coutant <ccoutant@gmail.com> | 2016-12-19 19:19:46 -0800 |
---|---|---|
committer | Cary Coutant <ccoutant@gmail.com> | 2016-12-19 19:20:10 -0800 |
commit | 092e01962dfbe7db9f5e57ca365b8ca56b4aa96a (patch) | |
tree | 8536e452ded7ada26822d853f45e07cd40262bee /gold/script.cc | |
parent | 3e67a37820a2838cdbd50f3f697ddc929443ceaa (diff) | |
download | gdb-092e01962dfbe7db9f5e57ca365b8ca56b4aa96a.zip gdb-092e01962dfbe7db9f5e57ca365b8ca56b4aa96a.tar.gz gdb-092e01962dfbe7db9f5e57ca365b8ca56b4aa96a.tar.bz2 |
Fix read-beyond-end-of-buffer error in script parsing.
2016-12-19 Cary Coutant <ccoutant@gmail.com>
gold/
PR gold/20949
* script.cc (Lex::get_token): Don't look ahead past NUL characters.
Diffstat (limited to 'gold/script.cc')
-rw-r--r-- | gold/script.cc | 35 |
1 files changed, 21 insertions, 14 deletions
diff --git a/gold/script.cc b/gold/script.cc index bb8b437..e4d0593 100644 --- a/gold/script.cc +++ b/gold/script.cc @@ -764,12 +764,6 @@ Lex::get_token(const char** pp) while (true) { - if (*p == '\0') - { - *pp = p; - return this->make_eof_token(p); - } - // Skip whitespace quickly. while (*p == ' ' || *p == '\t' || *p == '\r') ++p; @@ -782,8 +776,18 @@ Lex::get_token(const char** pp) continue; } + char c0 = *p; + + if (c0 == '\0') + { + *pp = p; + return this->make_eof_token(p); + } + + char c1 = p[1]; + // Skip C style comments. - if (p[0] == '/' && p[1] == '*') + if (c0 == '/' && c1 == '*') { int lineno = this->lineno_; int charpos = p - this->linestart_ + 1; @@ -797,7 +801,7 @@ Lex::get_token(const char** pp) } // Skip line comments. - if (*p == '#') + if (c0 == '#') { *pp = p + 1; if (!this->skip_line_comment(pp)) @@ -807,7 +811,7 @@ Lex::get_token(const char** pp) } // Check for a name. - if (this->can_start_name(p[0], p[1])) + if (this->can_start_name(c0, c1)) return this->gather_token(Token::TOKEN_STRING, &Lex::can_continue_name, p, p + 1, pp); @@ -820,35 +824,38 @@ Lex::get_token(const char** pp) return this->gather_quoted_string(pp); } + // Be careful not to lookahead past the end of the buffer. + char c2 = (c1 == '\0' ? '\0' : p[2]); + // Check for a number. - if (this->can_start_hex(p[0], p[1], p[2])) + if (this->can_start_hex(c0, c1, c2)) return this->gather_token(Token::TOKEN_INTEGER, &Lex::can_continue_hex, p, p + 3, pp); - if (Lex::can_start_number(p[0])) + if (Lex::can_start_number(c0)) return this->gather_token(Token::TOKEN_INTEGER, &Lex::can_continue_number, p, p + 1, pp); // Check for operators. - int opcode = Lex::three_char_operator(p[0], p[1], p[2]); + int opcode = Lex::three_char_operator(c0, c1, c2); if (opcode != 0) { *pp = p + 3; return this->make_token(opcode, p); } - opcode = Lex::two_char_operator(p[0], p[1]); + opcode = Lex::two_char_operator(c0, c1); if (opcode != 0) { *pp = p + 2; return this->make_token(opcode, p); } - opcode = Lex::one_char_operator(p[0]); + opcode = Lex::one_char_operator(c0); if (opcode != 0) { *pp = p + 1; |