aboutsummaryrefslogtreecommitdiff
path: root/gold
diff options
context:
space:
mode:
authorCary Coutant <ccoutant@gmail.com>2016-12-19 19:19:46 -0800
committerCary Coutant <ccoutant@gmail.com>2016-12-19 19:20:10 -0800
commit092e01962dfbe7db9f5e57ca365b8ca56b4aa96a (patch)
tree8536e452ded7ada26822d853f45e07cd40262bee /gold
parent3e67a37820a2838cdbd50f3f697ddc929443ceaa (diff)
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')
-rw-r--r--gold/ChangeLog5
-rw-r--r--gold/script.cc35
2 files changed, 26 insertions, 14 deletions
diff --git a/gold/ChangeLog b/gold/ChangeLog
index 3c89094da3..ecd958f940 100644
--- a/gold/ChangeLog
+++ b/gold/ChangeLog
@@ -1,5 +1,10 @@
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
PR gold/20983
* layout.h (Layout::choose_output_section): Add match_input_spec
diff --git a/gold/script.cc b/gold/script.cc
index bb8b4372f8..e4d0593cb0 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;