From e69d20e10bf040c78a98d42514453d990aa56217 Mon Sep 17 00:00:00 2001 From: Nikolai Kosjar <nikolai.kosjar@theqtcompany.com> Date: Mon, 11 May 2015 12:31:53 +0200 Subject: [PATCH] C++: Limit parsing of initializer clauses ...to prevent out of memory crash for generated tables. Change-Id: I8f9f51829fcce5bccfe0dba8852023f8dd7d6e37 Task-number: QTCREATORBUG-14390 Reviewed-by: Eike Ziller <eike.ziller@theqtcompany.com> Reviewed-by: Erik Verbruggen <erik.verbruggen@theqtcompany.com> --- src/libs/3rdparty/cplusplus/Parser.cpp | 15 +++++++++++++-- src/libs/3rdparty/cplusplus/Parser.h | 2 ++ 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/src/libs/3rdparty/cplusplus/Parser.cpp b/src/libs/3rdparty/cplusplus/Parser.cpp index 4f44d614658..7c330ce3300 100644 --- a/src/libs/3rdparty/cplusplus/Parser.cpp +++ b/src/libs/3rdparty/cplusplus/Parser.cpp @@ -42,6 +42,7 @@ #define CPLUSPLUS_NO_DEBUG_RULE #define MAX_EXPRESSION_DEPTH 100 #define MAX_STATEMENT_DEPTH 100 +#define MAX_INITIALIZER_CLAUSE_DEPTH 2000 using namespace CPlusPlus; @@ -2785,6 +2786,8 @@ bool Parser::parseInitializerList0x(ExpressionListAST *&node) ExpressionListAST **expression_list_ptr = &node; ExpressionAST *expression = 0; + _initializerClauseDepth.push(1); + if (parseInitializerClause0x(expression)) { *expression_list_ptr = new (_pool) ExpressionListAST; (*expression_list_ptr)->value = expression; @@ -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)) 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 if (parseInitializerClause0x(expression)) { @@ -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) diff --git a/src/libs/3rdparty/cplusplus/Parser.h b/src/libs/3rdparty/cplusplus/Parser.h index 4a2a6dfb7e0..7f7f2d28c0f 100644 --- a/src/libs/3rdparty/cplusplus/Parser.h +++ b/src/libs/3rdparty/cplusplus/Parser.h @@ -27,6 +27,7 @@ #include "TranslationUnit.h" #include "MemoryPool.h" #include <map> +#include <stack> namespace CPlusPlus { @@ -321,6 +322,7 @@ private: bool _inExpressionStatement: 1; int _expressionDepth; int _statementDepth; + std::stack<int> _initializerClauseDepth; MemoryPool _expressionStatementTempPool; std::map<unsigned, TemplateArgumentListEntry> _templateArgumentList; -- GitLab