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.
This commit is contained in:
Stephen Kelly
2012-10-12 17:34:16 +02:00
committed by Brad King
parent 145a4af8d3
commit e7230c71fd
3 changed files with 68 additions and 13 deletions
+24 -13
View File
@@ -77,6 +77,7 @@ static void extendResult(std::vector<cmGeneratorExpressionEvaluator*> &result,
void cmGeneratorExpressionParser::ParseGeneratorExpression(
std::vector<cmGeneratorExpressionEvaluator*> &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<std::vector<cmGeneratorExpressionToken>::const_iterator>
commaTokens;
std::vector<cmGeneratorExpressionToken>::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<cmGeneratorExpressionEvaluator*> &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.");
}