Commit e69d20e1 authored by Nikolai Kosjar's avatar Nikolai Kosjar
Browse files

C++: Limit parsing of initializer clauses



...to prevent out of memory crash for generated tables.

Change-Id: I8f9f51829fcce5bccfe0dba8852023f8dd7d6e37
Task-number: QTCREATORBUG-14390
Reviewed-by: default avatarEike Ziller <eike.ziller@theqtcompany.com>
Reviewed-by: default avatarErik Verbruggen <erik.verbruggen@theqtcompany.com>
parent 71a0d2dd
...@@ -42,6 +42,7 @@ ...@@ -42,6 +42,7 @@
#define CPLUSPLUS_NO_DEBUG_RULE #define CPLUSPLUS_NO_DEBUG_RULE
#define MAX_EXPRESSION_DEPTH 100 #define MAX_EXPRESSION_DEPTH 100
#define MAX_STATEMENT_DEPTH 100 #define MAX_STATEMENT_DEPTH 100
#define MAX_INITIALIZER_CLAUSE_DEPTH 2000
using namespace CPlusPlus; using namespace CPlusPlus;
...@@ -2785,6 +2786,8 @@ bool Parser::parseInitializerList0x(ExpressionListAST *&node) ...@@ -2785,6 +2786,8 @@ bool Parser::parseInitializerList0x(ExpressionListAST *&node)
ExpressionListAST **expression_list_ptr = &node; ExpressionListAST **expression_list_ptr = &node;
ExpressionAST *expression = 0; ExpressionAST *expression = 0;
_initializerClauseDepth.push(1);
if (parseInitializerClause0x(expression)) { if (parseInitializerClause0x(expression)) {
*expression_list_ptr = new (_pool) ExpressionListAST; *expression_list_ptr = new (_pool) ExpressionListAST;
(*expression_list_ptr)->value = expression; (*expression_list_ptr)->value = expression;
...@@ -2793,7 +2796,11 @@ bool Parser::parseInitializerList0x(ExpressionListAST *&node) ...@@ -2793,7 +2796,11 @@ bool Parser::parseInitializerList0x(ExpressionListAST *&node)
if (_languageFeatures.cxx11Enabled && LA() == T_DOT_DOT_DOT && (LA(2) == T_COMMA || LA(2) == T_RBRACE || LA(2) == T_RPAREN)) if (_languageFeatures.cxx11Enabled && LA() == T_DOT_DOT_DOT && (LA(2) == T_COMMA || LA(2) == T_RBRACE || LA(2) == T_RPAREN))
consumeToken(); // ### create an argument pack consumeToken(); // ### create an argument pack
while (LA() == T_COMMA && LA(2) != T_RBRACE) { for (++_initializerClauseDepth.top();
LA() == T_COMMA
&& LA(2) != T_RBRACE
&& _initializerClauseDepth.top() <= MAX_INITIALIZER_CLAUSE_DEPTH;
++_initializerClauseDepth.top()) {
consumeToken(); // consume T_COMMA consumeToken(); // consume T_COMMA
if (parseInitializerClause0x(expression)) { if (parseInitializerClause0x(expression)) {
...@@ -2808,7 +2815,11 @@ bool Parser::parseInitializerList0x(ExpressionListAST *&node) ...@@ -2808,7 +2815,11 @@ bool Parser::parseInitializerList0x(ExpressionListAST *&node)
} }
} }
return true; const bool result = _initializerClauseDepth.top() <= MAX_INITIALIZER_CLAUSE_DEPTH;
_initializerClauseDepth.pop();
if (!result)
warning(cursor(), "Reached parse limit for initializer clause");
return result;
} }
bool Parser::parseBracedInitList0x(ExpressionAST *&node) bool Parser::parseBracedInitList0x(ExpressionAST *&node)
......
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#include "TranslationUnit.h" #include "TranslationUnit.h"
#include "MemoryPool.h" #include "MemoryPool.h"
#include <map> #include <map>
#include <stack>
namespace CPlusPlus { namespace CPlusPlus {
...@@ -321,6 +322,7 @@ private: ...@@ -321,6 +322,7 @@ private:
bool _inExpressionStatement: 1; bool _inExpressionStatement: 1;
int _expressionDepth; int _expressionDepth;
int _statementDepth; int _statementDepth;
std::stack<int> _initializerClauseDepth;
MemoryPool _expressionStatementTempPool; MemoryPool _expressionStatementTempPool;
std::map<unsigned, TemplateArgumentListEntry> _templateArgumentList; std::map<unsigned, TemplateArgumentListEntry> _templateArgumentList;
......
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