From 36eef302c0b8ecb992c5d4b01562bcaef543b6fc Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Tue, 13 Aug 2013 13:32:27 +0200 Subject: Genex: Fix segfault when parsing ends with parameter expectation. The extendResult method expects a non-empty parameters vector, as assured by the normal case. Avoid calling the method when the parser finds an incomplete generator expression, but has already entered the state of expecting to find parameters. --- Source/cmGeneratorExpressionParser.cxx | 20 +++++++++++++++++++- Tests/GeneratorExpression/CMakeLists.txt | 2 ++ Tests/GeneratorExpression/check-part3.cmake | 2 ++ 3 files changed, 23 insertions(+), 1 deletion(-) diff --git a/Source/cmGeneratorExpressionParser.cxx b/Source/cmGeneratorExpressionParser.cxx index a619cec..e1fb8f1 100644 --- a/Source/cmGeneratorExpressionParser.cxx +++ b/Source/cmGeneratorExpressionParser.cxx @@ -126,6 +126,9 @@ void cmGeneratorExpressionParser::ParseGeneratorExpression( std::vector::const_iterator> commaTokens; std::vector::const_iterator colonToken; + + bool emptyParamTermination = false; + if (this->it != this->Tokens.end() && this->it->TokenType == cmGeneratorExpressionToken::ColonSeparator) { @@ -133,6 +136,10 @@ void cmGeneratorExpressionParser::ParseGeneratorExpression( parameters.resize(parameters.size() + 1); assert(this->it != this->Tokens.end()); ++this->it; + if(this->it == this->Tokens.end()) + { + emptyParamTermination = true; + } while (this->it != this->Tokens.end() && this->it->TokenType == cmGeneratorExpressionToken::CommaSeparator) @@ -141,6 +148,10 @@ void cmGeneratorExpressionParser::ParseGeneratorExpression( parameters.resize(parameters.size() + 1); assert(this->it != this->Tokens.end()); ++this->it; + if(this->it == this->Tokens.end()) + { + emptyParamTermination = true; + } } while (this->it != this->Tokens.end() && this->it->TokenType == cmGeneratorExpressionToken::ColonSeparator) @@ -164,6 +175,10 @@ void cmGeneratorExpressionParser::ParseGeneratorExpression( parameters.resize(parameters.size() + 1); assert(this->it != this->Tokens.end()); ++this->it; + if(this->it == this->Tokens.end()) + { + emptyParamTermination = true; + } } while (this->it != this->Tokens.end() && this->it->TokenType == cmGeneratorExpressionToken::ColonSeparator) @@ -203,7 +218,10 @@ void cmGeneratorExpressionParser::ParseGeneratorExpression( assert(parameters.size() > commaTokens.size()); for ( ; pit != pend; ++pit, ++commaIt) { - extendResult(result, *pit); + if (!pit->empty() && !emptyParamTermination) + { + extendResult(result, *pit); + } if (commaIt != commaTokens.end()) { extendText(result, *commaIt); diff --git a/Tests/GeneratorExpression/CMakeLists.txt b/Tests/GeneratorExpression/CMakeLists.txt index 9ee4fc5..4d8d7ed 100644 --- a/Tests/GeneratorExpression/CMakeLists.txt +++ b/Tests/GeneratorExpression/CMakeLists.txt @@ -184,6 +184,8 @@ add_custom_target(check-part3 ALL -Dtest_alias_file_exe=$,$> -Dtest_alias_file_lib=$,$> -Dtest_alias_target_name=$,$> + -Dtest_early_termination_1=$<$<1:>: + -Dtest_early_termination_2=$<$<1:>:, -P ${CMAKE_CURRENT_SOURCE_DIR}/check-part3.cmake COMMAND ${CMAKE_COMMAND} -E echo "check done (part 3 of 3)" VERBATIM diff --git a/Tests/GeneratorExpression/check-part3.cmake b/Tests/GeneratorExpression/check-part3.cmake index 5a6a441..74a596c 100644 --- a/Tests/GeneratorExpression/check-part3.cmake +++ b/Tests/GeneratorExpression/check-part3.cmake @@ -24,3 +24,5 @@ endforeach() check(test_alias_file_exe "1") check(test_alias_file_lib "1") check(test_alias_target_name "1") +check(test_early_termination_1 "$<:") +check(test_early_termination_2 "$<:,") -- cgit v0.12