Fixed three unique crashs on garbage code (#6613).

Removed redundant copy of string in templatesimplifier.cpp
This commit is contained in:
PKEuS 2015-04-01 12:43:03 +02:00
parent 4c3a7661c3
commit 0d37c4df04
4 changed files with 22 additions and 13 deletions

View File

@ -264,7 +264,7 @@ unsigned int TemplateSimplifier::templateParameters(const Token *tok)
tok = tok->next(); tok = tok->next();
while (Token::Match(tok, "%name% ::")) { while (Token::Match(tok, "%name% ::")) {
tok = tok->tokAt(2); tok = tok->tokAt(2);
if (tok->str() == "*") // Ticket #5759: Class member pointer as a template argument; skip '*' if (tok && tok->str() == "*") // Ticket #5759: Class member pointer as a template argument; skip '*'
tok = tok->next(); tok = tok->next();
} }
if (!tok) if (!tok)
@ -1231,18 +1231,18 @@ bool TemplateSimplifier::simplifyTemplateInstantiations(
// New type.. // New type..
std::vector<const Token *> typesUsedInTemplateInstantiation; std::vector<const Token *> typesUsedInTemplateInstantiation;
std::string typeForNewNameStr; std::string typeForNewName;
std::string templateMatchPattern(name + " < "); std::string templateMatchPattern(name + " < ");
unsigned int indentlevel = 0; unsigned int indentlevel = 0;
for (const Token *tok3 = tok2->tokAt(2); tok3 && (indentlevel > 0 || tok3->str() != ">"); tok3 = tok3->next()) { for (const Token *tok3 = tok2->tokAt(2); tok3 && (indentlevel > 0 || tok3->str() != ">"); tok3 = tok3->next()) {
// #2648 - unhandled parentheses => bail out // #2648 - unhandled parentheses => bail out
// #2721 - unhandled [ => bail out // #2721 - unhandled [ => bail out
if (Token::Match(tok3, "(|[")) { if (Token::Match(tok3, "(|[")) {
typeForNewNameStr.clear(); typeForNewName.clear();
break; break;
} }
if (!tok3->next()) { if (!tok3->next()) {
typeForNewNameStr.clear(); typeForNewName.clear();
break; break;
} }
if (Token::Match(tok3->tokAt(-2), "[<,] %name% <") && templateParameters(tok3) > 0) if (Token::Match(tok3->tokAt(-2), "[<,] %name% <") && templateParameters(tok3) > 0)
@ -1259,16 +1259,15 @@ bool TemplateSimplifier::simplifyTemplateInstantiations(
// add additional type information // add additional type information
if (!constconst && tok3->str() != "class") { if (!constconst && tok3->str() != "class") {
if (tok3->isUnsigned()) if (tok3->isUnsigned())
typeForNewNameStr += "unsigned"; typeForNewName += "unsigned";
else if (tok3->isSigned()) else if (tok3->isSigned())
typeForNewNameStr += "signed"; typeForNewName += "signed";
if (tok3->isLong()) if (tok3->isLong())
typeForNewNameStr += "long"; typeForNewName += "long";
typeForNewNameStr += tok3->str(); typeForNewName += tok3->str();
} }
} }
templateMatchPattern += ">"; templateMatchPattern += ">";
const std::string typeForNewName(typeForNewNameStr);
if (typeForNewName.empty() || typeParametersInDeclaration.size() != typesUsedInTemplateInstantiation.size()) { if (typeForNewName.empty() || typeParametersInDeclaration.size() != typesUsedInTemplateInstantiation.size()) {
if (_settings->debugwarnings && errorlogger) { if (_settings->debugwarnings && errorlogger) {

View File

@ -2601,9 +2601,10 @@ void Tokenizer::setVarId()
} else if (!executableScope.top() && tok->str() == "(" && isFunctionHead(tok, ";")) { } else if (!executableScope.top() && tok->str() == "(" && isFunctionHead(tok, ";")) {
scopeInfo.push(variableId); scopeInfo.push(variableId);
} else if (!executableScope.top() && tok->str() == ")" && isFunctionHead(tok, ";")) { } else if (!executableScope.top() && tok->str() == ")" && isFunctionHead(tok, ";")) {
if (scopeInfo.empty())
cppcheckError(tok);
variableId.swap(scopeInfo.top()); variableId.swap(scopeInfo.top());
scopeInfo.pop(); scopeInfo.pop();
} else if (tok->str() == "{") { } else if (tok->str() == "{") {
// parse anonymous unions as part of the current scope // parse anonymous unions as part of the current scope
if (!(tok->strAt(-1) == "union" && Token::simpleMatch(tok->link(), "} ;"))) { if (!(tok->strAt(-1) == "union" && Token::simpleMatch(tok->link(), "} ;"))) {

View File

@ -298,16 +298,16 @@ bool TokenList::createTokens(std::istream &code, const std::string& file0)
if (ch == '.' && if (ch == '.' &&
!CurrentToken.empty() && !CurrentToken.empty() &&
std::isdigit(CurrentToken[0])) { std::isdigit((unsigned char)CurrentToken[0])) {
// Don't separate doubles "5.4" // Don't separate doubles "5.4"
} else if (std::strchr("+-", ch) && } else if (std::strchr("+-", ch) &&
CurrentToken.length() > 0 && CurrentToken.length() > 0 &&
std::isdigit(CurrentToken[0]) && std::isdigit((unsigned char)CurrentToken[0]) &&
(CurrentToken[CurrentToken.length()-1] == 'e' || (CurrentToken[CurrentToken.length()-1] == 'e' ||
CurrentToken[CurrentToken.length()-1] == 'E') && CurrentToken[CurrentToken.length()-1] == 'E') &&
!MathLib::isHex(CurrentToken)) { !MathLib::isHex(CurrentToken)) {
// Don't separate doubles "4.2e+10" // Don't separate doubles "4.2e+10"
} else if (CurrentToken.empty() && ch == '.' && std::isdigit(code.peek())) { } else if (CurrentToken.empty() && ch == '.' && std::isdigit((unsigned char)code.peek())) {
// tokenize .125 into 0.125 // tokenize .125 into 0.125
CurrentToken = "0"; CurrentToken = "0";
} else if (std::strchr("+-*/%&|^?!=<>[](){};:,.~\n ", ch)) { } else if (std::strchr("+-*/%&|^?!=<>[](){};:,.~\n ", ch)) {

View File

@ -71,6 +71,7 @@ private:
TEST_CASE(garbageCode30); // #5867 TEST_CASE(garbageCode30); // #5867
TEST_CASE(garbageCode31); // #6539 TEST_CASE(garbageCode31); // #6539
TEST_CASE(garbageCode32); // #6135 TEST_CASE(garbageCode32); // #6135
TEST_CASE(garbageCode33); // #6613
TEST_CASE(garbageValueFlow); TEST_CASE(garbageValueFlow);
TEST_CASE(garbageSymbolDatabase); TEST_CASE(garbageSymbolDatabase);
@ -401,6 +402,14 @@ private:
checkCode(" ( * const ( size_t ) ; foo )"); checkCode(" ( * const ( size_t ) ; foo )");
} }
void garbageCode33() { // #6613
ASSERT_THROW(checkCode("main(()B{});"), InternalError);
checkCode("f::y:y : <x::");
checkCode("\xe2u.");
}
void garbageValueFlow() { void garbageValueFlow() {
// #6089 // #6089
const char* code = "{} int foo(struct, x1, struct x2, x3, int, x5, x6, x7)\n" const char* code = "{} int foo(struct, x1, struct x2, x3, int, x5, x6, x7)\n"