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.
This commit is contained in:
Cary Coutant 2016-12-19 19:19:46 -08:00
parent 3e67a37820
commit 092e01962d
2 changed files with 26 additions and 14 deletions

View File

@ -1,3 +1,8 @@
2016-12-19 Cary Coutant <ccoutant@gmail.com>
PR gold/20949
* script.cc (Lex::get_token): Don't look ahead past NUL characters.
2016-12-19 Cary Coutant <ccoutant@gmail.com>
PR gold/14676

View File

@ -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;