Commit d78e33a8 by Corentin Wallez Committed by Commit Bot

preprocessor: Fix lineno overflow on line continuations

BUG=chromium:774807 Change-Id: I4b3fbee31683f411810080572cfff0f8307b93bf Reviewed-on: https://chromium-review.googlesource.com/744183 Commit-Queue: Corentin Wallez <cwallez@chromium.org> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org>
parent 3590555d
...@@ -118,6 +118,8 @@ const char *Diagnostics::message(ID id) ...@@ -118,6 +118,8 @@ const char *Diagnostics::message(ID id)
return "extension directive must occur before any non-preprocessor tokens in ESSL3"; return "extension directive must occur before any non-preprocessor tokens in ESSL3";
case PP_UNDEFINED_SHIFT: case PP_UNDEFINED_SHIFT:
return "shift exponent is negative or undefined"; return "shift exponent is negative or undefined";
case PP_TOKENIZER_ERROR:
return "internal tokenizer error";
// Errors end. // Errors end.
// Warnings begin. // Warnings begin.
case PP_EOF_IN_DIRECTIVE: case PP_EOF_IN_DIRECTIVE:
......
...@@ -61,6 +61,11 @@ size_t Input::read(char *buf, size_t maxSize, int *lineNo) ...@@ -61,6 +61,11 @@ size_t Input::read(char *buf, size_t maxSize, int *lineNo)
{ {
// Line continuation of backslash + newline. // Line continuation of backslash + newline.
skipChar(); skipChar();
// Fake an EOF if the line number would overflow.
if (*lineNo == INT_MAX)
{
return 0;
}
++(*lineNo); ++(*lineNo);
} }
else if (c != nullptr && (*c) == '\r') else if (c != nullptr && (*c) == '\r')
...@@ -71,6 +76,11 @@ size_t Input::read(char *buf, size_t maxSize, int *lineNo) ...@@ -71,6 +76,11 @@ size_t Input::read(char *buf, size_t maxSize, int *lineNo)
{ {
skipChar(); skipChar();
} }
// Fake an EOF if the line number would overflow.
if (*lineNo == INT_MAX)
{
return 0;
}
++(*lineNo); ++(*lineNo);
} }
else else
......
...@@ -1680,11 +1680,18 @@ case YY_STATE_EOF(COMMENT): ...@@ -1680,11 +1680,18 @@ case YY_STATE_EOF(COMMENT):
yylloc->line = yylineno; yylloc->line = yylineno;
yylval->clear(); yylval->clear();
if (YY_START == COMMENT) // Line number overflows fake EOFs to exit early, check for this case.
if (yylineno == INT_MAX)
{
yyextra->diagnostics->report(pp::Diagnostics::PP_TOKENIZER_ERROR,
pp::SourceLocation(yyfileno, yylineno),
"Integer overflow on line number");
}
else if (YY_START == COMMENT)
{ {
yyextra->diagnostics->report(pp::Diagnostics::PP_EOF_IN_COMMENT, yyextra->diagnostics->report(pp::Diagnostics::PP_EOF_IN_COMMENT,
pp::SourceLocation(yyfileno, yylineno), pp::SourceLocation(yyfileno, yylineno),
""); "EOF while in a comment");
} }
yyterminate(); yyterminate();
} }
......
...@@ -277,11 +277,17 @@ FRACTIONAL_CONSTANT ({DIGIT}*"."{DIGIT}+)|({DIGIT}+".") ...@@ -277,11 +277,17 @@ FRACTIONAL_CONSTANT ({DIGIT}*"."{DIGIT}+)|({DIGIT}+".")
yylloc->line = yylineno; yylloc->line = yylineno;
yylval->clear(); yylval->clear();
if (YY_START == COMMENT) // Line number overflows fake EOFs to exit early, check for this case.
if (yylineno == INT_MAX) {
yyextra->diagnostics->report(pp::Diagnostics::PP_TOKENIZER_ERROR,
pp::SourceLocation(yyfileno, yylineno),
"Integer overflow on line number");
}
else if (YY_START == COMMENT)
{ {
yyextra->diagnostics->report(pp::Diagnostics::PP_EOF_IN_COMMENT, yyextra->diagnostics->report(pp::Diagnostics::PP_EOF_IN_COMMENT,
pp::SourceLocation(yyfileno, yylineno), pp::SourceLocation(yyfileno, yylineno),
""); "EOF while in a comment");
} }
yyterminate(); yyterminate();
} }
......
...@@ -270,7 +270,7 @@ TEST_F(LocationTest, LineDirectiveMissingNewline) ...@@ -270,7 +270,7 @@ TEST_F(LocationTest, LineDirectiveMissingNewline)
// Test for an error being generated when the line number overflows - regular version // Test for an error being generated when the line number overflows - regular version
TEST_F(LocationTest, LineOverflowRegular) TEST_F(LocationTest, LineOverflowRegular)
{ {
const char *str = "#line 2147483647\n\n"; const char *str = "#line 0x7FFFFFFF\n\n";
ASSERT_TRUE(mPreprocessor.init(1, &str, NULL)); ASSERT_TRUE(mPreprocessor.init(1, &str, NULL));
...@@ -285,7 +285,39 @@ TEST_F(LocationTest, LineOverflowRegular) ...@@ -285,7 +285,39 @@ TEST_F(LocationTest, LineOverflowRegular)
// Test for an error being generated when the line number overflows - inside /* */ comment version // Test for an error being generated when the line number overflows - inside /* */ comment version
TEST_F(LocationTest, LineOverflowInComment) TEST_F(LocationTest, LineOverflowInComment)
{ {
const char *str = "#line 2147483647\n/*\n*/"; const char *str = "#line 0x7FFFFFFF\n/*\n*/";
ASSERT_TRUE(mPreprocessor.init(1, &str, NULL));
using testing::_;
// Error reported about EOF.
EXPECT_CALL(mDiagnostics, print(pp::Diagnostics::PP_TOKENIZER_ERROR, _, _));
pp::Token token;
mPreprocessor.lex(&token);
}
// Test for an error being generated when the line number overflows - inside \n continuation
// version
TEST_F(LocationTest, LineOverflowInContinuationN)
{
const char *str = "#line 0x7FFFFFFF\n \\\n\n";
ASSERT_TRUE(mPreprocessor.init(1, &str, NULL));
using testing::_;
// Error reported about EOF.
EXPECT_CALL(mDiagnostics, print(pp::Diagnostics::PP_TOKENIZER_ERROR, _, _));
pp::Token token;
mPreprocessor.lex(&token);
}
// Test for an error being generated when the line number overflows - inside \r\n continuation
// version
TEST_F(LocationTest, LineOverflowInContinuationRN)
{
const char *str = "#line 0x7FFFFFFF\n \\\r\n\n";
ASSERT_TRUE(mPreprocessor.init(1, &str, NULL)); ASSERT_TRUE(mPreprocessor.init(1, &str, NULL));
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment