Skip to content

Commit 0d37c4d

Browse files
committed
Fixed three unique crashs on garbage code (cppcheck-opensource#6613).
Removed redundant copy of string in templatesimplifier.cpp
1 parent 4c3a766 commit 0d37c4d

4 files changed

Lines changed: 22 additions & 13 deletions

File tree

lib/templatesimplifier.cpp

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -264,7 +264,7 @@ unsigned int TemplateSimplifier::templateParameters(const Token *tok)
264264
tok = tok->next();
265265
while (Token::Match(tok, "%name% ::")) {
266266
tok = tok->tokAt(2);
267-
if (tok->str() == "*") // Ticket #5759: Class member pointer as a template argument; skip '*'
267+
if (tok && tok->str() == "*") // Ticket #5759: Class member pointer as a template argument; skip '*'
268268
tok = tok->next();
269269
}
270270
if (!tok)
@@ -1231,18 +1231,18 @@ bool TemplateSimplifier::simplifyTemplateInstantiations(
12311231

12321232
// New type..
12331233
std::vector<const Token *> typesUsedInTemplateInstantiation;
1234-
std::string typeForNewNameStr;
1234+
std::string typeForNewName;
12351235
std::string templateMatchPattern(name + " < ");
12361236
unsigned int indentlevel = 0;
12371237
for (const Token *tok3 = tok2->tokAt(2); tok3 && (indentlevel > 0 || tok3->str() != ">"); tok3 = tok3->next()) {
12381238
// #2648 - unhandled parentheses => bail out
12391239
// #2721 - unhandled [ => bail out
12401240
if (Token::Match(tok3, "(|[")) {
1241-
typeForNewNameStr.clear();
1241+
typeForNewName.clear();
12421242
break;
12431243
}
12441244
if (!tok3->next()) {
1245-
typeForNewNameStr.clear();
1245+
typeForNewName.clear();
12461246
break;
12471247
}
12481248
if (Token::Match(tok3->tokAt(-2), "[<,] %name% <") && templateParameters(tok3) > 0)
@@ -1259,16 +1259,15 @@ bool TemplateSimplifier::simplifyTemplateInstantiations(
12591259
// add additional type information
12601260
if (!constconst && tok3->str() != "class") {
12611261
if (tok3->isUnsigned())
1262-
typeForNewNameStr += "unsigned";
1262+
typeForNewName += "unsigned";
12631263
else if (tok3->isSigned())
1264-
typeForNewNameStr += "signed";
1264+
typeForNewName += "signed";
12651265
if (tok3->isLong())
1266-
typeForNewNameStr += "long";
1267-
typeForNewNameStr += tok3->str();
1266+
typeForNewName += "long";
1267+
typeForNewName += tok3->str();
12681268
}
12691269
}
12701270
templateMatchPattern += ">";
1271-
const std::string typeForNewName(typeForNewNameStr);
12721271

12731272
if (typeForNewName.empty() || typeParametersInDeclaration.size() != typesUsedInTemplateInstantiation.size()) {
12741273
if (_settings->debugwarnings && errorlogger) {

lib/tokenize.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2601,9 +2601,10 @@ void Tokenizer::setVarId()
26012601
} else if (!executableScope.top() && tok->str() == "(" && isFunctionHead(tok, ";")) {
26022602
scopeInfo.push(variableId);
26032603
} else if (!executableScope.top() && tok->str() == ")" && isFunctionHead(tok, ";")) {
2604+
if (scopeInfo.empty())
2605+
cppcheckError(tok);
26042606
variableId.swap(scopeInfo.top());
26052607
scopeInfo.pop();
2606-
26072608
} else if (tok->str() == "{") {
26082609
// parse anonymous unions as part of the current scope
26092610
if (!(tok->strAt(-1) == "union" && Token::simpleMatch(tok->link(), "} ;"))) {

lib/tokenlist.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -298,16 +298,16 @@ bool TokenList::createTokens(std::istream &code, const std::string& file0)
298298

299299
if (ch == '.' &&
300300
!CurrentToken.empty() &&
301-
std::isdigit(CurrentToken[0])) {
301+
std::isdigit((unsigned char)CurrentToken[0])) {
302302
// Don't separate doubles "5.4"
303303
} else if (std::strchr("+-", ch) &&
304304
CurrentToken.length() > 0 &&
305-
std::isdigit(CurrentToken[0]) &&
305+
std::isdigit((unsigned char)CurrentToken[0]) &&
306306
(CurrentToken[CurrentToken.length()-1] == 'e' ||
307307
CurrentToken[CurrentToken.length()-1] == 'E') &&
308308
!MathLib::isHex(CurrentToken)) {
309309
// Don't separate doubles "4.2e+10"
310-
} else if (CurrentToken.empty() && ch == '.' && std::isdigit(code.peek())) {
310+
} else if (CurrentToken.empty() && ch == '.' && std::isdigit((unsigned char)code.peek())) {
311311
// tokenize .125 into 0.125
312312
CurrentToken = "0";
313313
} else if (std::strchr("+-*/%&|^?!=<>[](){};:,.~\n ", ch)) {

test/testgarbage.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ class TestGarbage : public TestFixture {
7171
TEST_CASE(garbageCode30); // #5867
7272
TEST_CASE(garbageCode31); // #6539
7373
TEST_CASE(garbageCode32); // #6135
74+
TEST_CASE(garbageCode33); // #6613
7475

7576
TEST_CASE(garbageValueFlow);
7677
TEST_CASE(garbageSymbolDatabase);
@@ -401,6 +402,14 @@ class TestGarbage : public TestFixture {
401402
checkCode(" ( * const ( size_t ) ; foo )");
402403
}
403404

405+
void garbageCode33() { // #6613
406+
ASSERT_THROW(checkCode("main(()B{});"), InternalError);
407+
408+
checkCode("f::y:y : <x::");
409+
410+
checkCode("\xe2u.");
411+
}
412+
404413
void garbageValueFlow() {
405414
// #6089
406415
const char* code = "{} int foo(struct, x1, struct x2, x3, int, x5, x6, x7)\n"

0 commit comments

Comments
 (0)