From e7230c71fdf9ed58b2e8fbf2064452a41ea57180 Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Fri, 12 Oct 2012 17:34:16 +0200 Subject: [PATCH] GenEx: Fix termination bugs in generator expression parser. Content which is incomplete as a generator expression could cause segfaults by advancing an iterator beyond end() and dereferencing it. Such incomplete generator expressions should be treated as plain text instead. --- Source/cmGeneratorExpressionParser.cxx | 37 +++++++++++++++--------- Tests/GeneratorExpression/CMakeLists.txt | 22 ++++++++++++++ Tests/GeneratorExpression/check.cmake | 22 ++++++++++++++ 3 files changed, 68 insertions(+), 13 deletions(-) diff --git a/Source/cmGeneratorExpressionParser.cxx b/Source/cmGeneratorExpressionParser.cxx index d09e412e5..341832a18 100644 --- a/Source/cmGeneratorExpressionParser.cxx +++ b/Source/cmGeneratorExpressionParser.cxx @@ -77,6 +77,7 @@ static void extendResult(std::vector &result, void cmGeneratorExpressionParser::ParseGeneratorExpression( std::vector &result) { + assert(this->it != this->Tokens.end()); unsigned int nestedLevel = this->NestingLevel; ++this->NestingLevel; @@ -98,7 +99,8 @@ void cmGeneratorExpressionParser::ParseGeneratorExpression( // ERROR } - if (this->it->TokenType == cmGeneratorExpressionToken::EndExpression) + if (this->it != this->Tokens.end() && + this->it->TokenType == cmGeneratorExpressionToken::EndExpression) { GeneratorExpressionContent *content = new GeneratorExpressionContent( startToken->Content, this->it->Content @@ -115,42 +117,50 @@ void cmGeneratorExpressionParser::ParseGeneratorExpression( std::vector::const_iterator> commaTokens; std::vector::const_iterator colonToken; - if (this->it->TokenType == cmGeneratorExpressionToken::ColonSeparator) + if (this->it != this->Tokens.end() && + this->it->TokenType == cmGeneratorExpressionToken::ColonSeparator) { colonToken = this->it; parameters.resize(parameters.size() + 1); ++this->it; - while (this->it->TokenType == cmGeneratorExpressionToken::CommaSeparator) + + while (this->it != this->Tokens.end() && + this->it->TokenType == cmGeneratorExpressionToken::CommaSeparator) { commaTokens.push_back(this->it); parameters.resize(parameters.size() + 1); ++this->it; } - while (this->it->TokenType == cmGeneratorExpressionToken::ColonSeparator) + while (this->it != this->Tokens.end() && + this->it->TokenType == cmGeneratorExpressionToken::ColonSeparator) { extendText(*(parameters.end() - 1), this->it); ++this->it; } - while(this->it->TokenType != cmGeneratorExpressionToken::EndExpression) + while (this->it != this->Tokens.end() && + this->it->TokenType != cmGeneratorExpressionToken::EndExpression) { this->ParseContent(*(parameters.end() - 1)); - while (this->it->TokenType == cmGeneratorExpressionToken::CommaSeparator) + if (this->it == this->Tokens.end()) + { + break; + } + while (this->it != this->Tokens.end() && + this->it->TokenType == cmGeneratorExpressionToken::CommaSeparator) { commaTokens.push_back(this->it); parameters.resize(parameters.size() + 1); ++this->it; } - while (this->it->TokenType == cmGeneratorExpressionToken::ColonSeparator) + while (this->it != this->Tokens.end() && + this->it->TokenType == cmGeneratorExpressionToken::ColonSeparator) { extendText(*(parameters.end() - 1), this->it); ++this->it; } - if (this->it == this->Tokens.end()) - { - break; - } } - if(this->it->TokenType == cmGeneratorExpressionToken::EndExpression) + if(this->it != this->Tokens.end() + && this->it->TokenType == cmGeneratorExpressionToken::EndExpression) { --this->NestingLevel; ++this->it; @@ -201,6 +211,7 @@ void cmGeneratorExpressionParser::ParseGeneratorExpression( void cmGeneratorExpressionParser::ParseContent( std::vector &result) { + assert(this->it != this->Tokens.end()); switch(this->it->TokenType) { case cmGeneratorExpressionToken::Text: @@ -245,5 +256,5 @@ void cmGeneratorExpressionParser::ParseContent( ++this->it; return; } - // Unreachable. Assert? + assert(!"Unhandled token in generator expression."); } diff --git a/Tests/GeneratorExpression/CMakeLists.txt b/Tests/GeneratorExpression/CMakeLists.txt index 4967ac0a7..cb01ec178 100644 --- a/Tests/GeneratorExpression/CMakeLists.txt +++ b/Tests/GeneratorExpression/CMakeLists.txt @@ -49,6 +49,28 @@ add_custom_target(check ALL -Dtest_colons_3=$<1:Qt5::Core> -Dtest_colons_4=$<1:C:\\CMake> -Dtest_colons_5=$<1:C:/CMake> + -Dtest_incomplete_1=$< + -Dtest_incomplete_2=$ + -Dtest_incomplete_6= + -Dtest_incomplete_7=$thing + -Dtest_incomplete_14=$< + -Dtest_incomplete_18=$<1:some,thing + -Dtest_incomplete_19=$<1:some,thing$ + -Dtest_incomplete_20=$ + -Dtest_incomplete_21=$ + -Dtest_incomplete_22=$") +check(test_incomplete_6 "") +check(test_incomplete_7 "$") +check(test_incomplete_20 "$") +check(test_incomplete_21 "$") +check(test_incomplete_22 "$