preprocessor: add a limit to the number of token expanded
BUG=angleproject:1522
BUG=chromium:648074
Change-Id: Ibf0858aaeb81933dd221ac82a49160169b48a495
Reviewed-on: https://chromium-review.googlesource.com/387211
Reviewed-by: Geoff Lang <geofflang@chromium.org>
Commit-Queue: Corentin Wallez <cwallez@chromium.org>
diff --git a/src/compiler/preprocessor/MacroExpander.cpp b/src/compiler/preprocessor/MacroExpander.cpp
index 51b69f8..a4519f2 100644
--- a/src/compiler/preprocessor/MacroExpander.cpp
+++ b/src/compiler/preprocessor/MacroExpander.cpp
@@ -15,6 +15,11 @@
namespace pp
{
+namespace
+{
+
+const size_t kMaxContextTokens = 10000;
+
class TokenLexer : public Lexer
{
public:
@@ -46,8 +51,10 @@
TokenVector::const_iterator mIter;
};
+} // anonymous namespace
+
MacroExpander::MacroExpander(Lexer *lexer, MacroSet *macroSet, Diagnostics *diagnostics)
- : mLexer(lexer), mMacroSet(macroSet), mDiagnostics(diagnostics)
+ : mLexer(lexer), mMacroSet(macroSet), mDiagnostics(diagnostics), mTotalTokensInContexts(0)
{
}
@@ -114,6 +121,7 @@
}
else
{
+ assert(mTotalTokensInContexts == 0);
mLexer->lex(token);
}
}
@@ -164,6 +172,7 @@
context->macro = ¯o;
context->replacements.swap(replacements);
mContextStack.push_back(context);
+ mTotalTokensInContexts += context->replacements.size();
return true;
}
@@ -179,6 +188,7 @@
assert(context->macro->expansionCount > 0);
context->macro->disabled = false;
context->macro->expansionCount--;
+ mTotalTokensInContexts -= context->replacements.size();
delete context;
}
@@ -321,6 +331,7 @@
// Pre-expand each argument before substitution.
// This step expands each argument individually before they are
// inserted into the macro body.
+ size_t numTokens = 0;
for (std::size_t i = 0; i < args->size(); ++i)
{
MacroArg &arg = args->at(i);
@@ -333,6 +344,12 @@
{
arg.push_back(token);
expander.lex(&token);
+ numTokens++;
+ if (numTokens + mTotalTokensInContexts > kMaxContextTokens)
+ {
+ mDiagnostics->report(Diagnostics::PP_OUT_OF_MEMORY, token.location, token.text);
+ return false;
+ }
}
}
return true;
@@ -344,6 +361,14 @@
{
for (std::size_t i = 0; i < macro.replacements.size(); ++i)
{
+ if (!replacements->empty() &&
+ replacements->size() + mTotalTokensInContexts > kMaxContextTokens)
+ {
+ const Token &token = replacements->back();
+ mDiagnostics->report(Diagnostics::PP_OUT_OF_MEMORY, token.location, token.text);
+ return;
+ }
+
const Token &repl = macro.replacements[i];
if (repl.type != Token::IDENTIFIER)
{
diff --git a/src/compiler/preprocessor/MacroExpander.h b/src/compiler/preprocessor/MacroExpander.h
index dbf9803..5e5dbe9 100644
--- a/src/compiler/preprocessor/MacroExpander.h
+++ b/src/compiler/preprocessor/MacroExpander.h
@@ -84,6 +84,7 @@
std::unique_ptr<Token> mReserveToken;
std::vector<MacroContext *> mContextStack;
+ size_t mTotalTokensInContexts;
};
} // namespace pp