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: Geoff Lang <geofflang@chromium.org>
diff --git a/src/compiler/preprocessor/DiagnosticsBase.cpp b/src/compiler/preprocessor/DiagnosticsBase.cpp
index 1b9575b..c89bc9f 100644
--- a/src/compiler/preprocessor/DiagnosticsBase.cpp
+++ b/src/compiler/preprocessor/DiagnosticsBase.cpp
@@ -118,6 +118,8 @@
return "extension directive must occur before any non-preprocessor tokens in ESSL3";
case PP_UNDEFINED_SHIFT:
return "shift exponent is negative or undefined";
+ case PP_TOKENIZER_ERROR:
+ return "internal tokenizer error";
// Errors end.
// Warnings begin.
case PP_EOF_IN_DIRECTIVE:
diff --git a/src/compiler/preprocessor/Input.cpp b/src/compiler/preprocessor/Input.cpp
index e5bcd8e..3a473f7 100644
--- a/src/compiler/preprocessor/Input.cpp
+++ b/src/compiler/preprocessor/Input.cpp
@@ -61,6 +61,11 @@
{
// Line continuation of backslash + newline.
skipChar();
+ // Fake an EOF if the line number would overflow.
+ if (*lineNo == INT_MAX)
+ {
+ return 0;
+ }
++(*lineNo);
}
else if (c != nullptr && (*c) == '\r')
@@ -71,6 +76,11 @@
{
skipChar();
}
+ // Fake an EOF if the line number would overflow.
+ if (*lineNo == INT_MAX)
+ {
+ return 0;
+ }
++(*lineNo);
}
else
diff --git a/src/compiler/preprocessor/Tokenizer.cpp b/src/compiler/preprocessor/Tokenizer.cpp
index 76b376b..d8a9b9a 100644
--- a/src/compiler/preprocessor/Tokenizer.cpp
+++ b/src/compiler/preprocessor/Tokenizer.cpp
@@ -1680,11 +1680,18 @@
yylloc->line = yylineno;
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,
pp::SourceLocation(yyfileno, yylineno),
- "");
+ "EOF while in a comment");
}
yyterminate();
}
diff --git a/src/compiler/preprocessor/Tokenizer.l b/src/compiler/preprocessor/Tokenizer.l
index 564f580..096812d 100644
--- a/src/compiler/preprocessor/Tokenizer.l
+++ b/src/compiler/preprocessor/Tokenizer.l
@@ -277,11 +277,17 @@
yylloc->line = yylineno;
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,
pp::SourceLocation(yyfileno, yylineno),
- "");
+ "EOF while in a comment");
}
yyterminate();
}
diff --git a/src/tests/preprocessor_tests/location_test.cpp b/src/tests/preprocessor_tests/location_test.cpp
index 995db0d..0b36e4e 100644
--- a/src/tests/preprocessor_tests/location_test.cpp
+++ b/src/tests/preprocessor_tests/location_test.cpp
@@ -270,7 +270,7 @@
// Test for an error being generated when the line number overflows - regular version
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));
@@ -285,7 +285,39 @@
// Test for an error being generated when the line number overflows - inside /* */ comment version
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));