浏览代码

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.
Stephen Kelly 12 年之前
父节点
当前提交
36eef302c0

+ 19 - 1
Source/cmGeneratorExpressionParser.cxx

@@ -126,6 +126,9 @@ void cmGeneratorExpressionParser::ParseGeneratorExpression(
   std::vector<std::vector<cmGeneratorExpressionToken>::const_iterator>
                                                             commaTokens;
   std::vector<cmGeneratorExpressionToken>::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);

+ 2 - 0
Tests/GeneratorExpression/CMakeLists.txt

@@ -184,6 +184,8 @@ add_custom_target(check-part3 ALL
     -Dtest_alias_file_exe=$<STREQUAL:$<TARGET_FILE:Alias::SomeExe>,$<TARGET_FILE:someexe>>
     -Dtest_alias_file_lib=$<STREQUAL:$<TARGET_FILE:Alias::SomeLib>,$<TARGET_FILE:empty1>>
     -Dtest_alias_target_name=$<STREQUAL:$<TARGET_PROPERTY:Alias::SomeLib,NAME>,$<TARGET_PROPERTY:empty1,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

+ 2 - 0
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 "$<:,")