diff --git a/lib/checkclass.cpp b/lib/checkclass.cpp index 4d19f2c91..b13143d80 100644 --- a/lib/checkclass.cpp +++ b/lib/checkclass.cpp @@ -641,20 +641,23 @@ void CheckClass::privateFunctions() for (func = scope->functionList.begin(); func != scope->functionList.end(); ++func) { const Token *ftok = func->start; - const Token *etok = ftok->link(); - - for (; ftok != etok; ftok = ftok->next()) + if (ftok) { - if (Token::Match(ftok, "%var% (")) + const Token *etok = ftok->link(); + + for (; ftok != etok; ftok = ftok->next()) { - // Remove function from FuncList - std::list::iterator it = FuncList.begin(); - while (it != FuncList.end()) + if (Token::Match(ftok, "%var% (")) { - if (ftok->str() == (*it)->str()) - FuncList.erase(it++); - else - ++it; + // Remove function from FuncList + std::list::iterator it = FuncList.begin(); + while (it != FuncList.end()) + { + if (ftok->str() == (*it)->str()) + FuncList.erase(it++); + else + ++it; + } } } } diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index 0eafe3ebb..a600a1a3a 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -899,7 +899,7 @@ const Token *SymbolDatabase::initBaseInfo(Scope *scope, const Token *tok) tok2 = tok2->next(); // check for invalid code - if (!tok2->next()) + if (!tok2 || !tok2->next()) return NULL; if (tok2->str() == "public") diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index cb23f4c39..54639fc35 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -1039,6 +1039,13 @@ void Tokenizer::simplifyTypedef() Token *namespaceStart = 0; Token *namespaceEnd = 0; + // check for invalid input + if (!tok->next()) + { + syntaxError(tok); + return; + } + if (Token::simpleMatch(tok->next(), "::") || Token::Match(tok->next(), "%type%")) { @@ -1071,6 +1078,13 @@ void Tokenizer::simplifyTypedef() else continue; // invalid input + // check for invalid input + if (!tok->tokAt(offset)) + { + syntaxError(tok); + return; + } + // check for template if (tok->tokAt(offset)->str() == "<") { @@ -3809,6 +3823,9 @@ void Tokenizer::simplifySizeof() if (tok->str() != "sizeof") continue; + if (!tok->next()) + break; + if (Token::simpleMatch(tok->next(), "sizeof")) continue; @@ -5977,6 +5994,9 @@ void Tokenizer::simplifyIfNotNull() { tok = tok->next(); + if (!tok) + break; + if (Token::simpleMatch(tok, "0 != (") || Token::Match(tok, "0 != %var%")) { @@ -7842,7 +7862,7 @@ void Tokenizer::simplifyEnum() } // check for a variable definition: enum {} x; - if (end->next()->str() != ";") + if (end->next() && end->next()->str() != ";") { Token *tempTok = end; diff --git a/test/testclass.cpp b/test/testclass.cpp index 7f80a053b..a4f727618 100644 --- a/test/testclass.cpp +++ b/test/testclass.cpp @@ -195,6 +195,7 @@ private: TEST_CASE(symboldatabase12); // ticket #2547 TEST_CASE(symboldatabase13); // ticket #2577 TEST_CASE(symboldatabase14); // ticket #2589 + TEST_CASE(symboldatabase15); // ticket #2591 } // Check the operator Equal @@ -5596,6 +5597,14 @@ private: ASSERT_EQUALS("", errout.str()); } + void symboldatabase15() + { + // ticket #2591 - segmentation fault + checkConst("struct A :\n"); + + ASSERT_EQUALS("", errout.str()); + } + }; REGISTER_TEST(TestClass) diff --git a/test/testsimplifytokens.cpp b/test/testsimplifytokens.cpp index 58273fa4a..3ee94725f 100644 --- a/test/testsimplifytokens.cpp +++ b/test/testsimplifytokens.cpp @@ -84,6 +84,7 @@ private: TEST_CASE(sizeof19); // #1891 - sizeof 'x' TEST_CASE(sizeof20); // #2024 - sizeof a) TEST_CASE(sizeof21); // #2232 - sizeof...(Args) + TEST_CASE(sizeof22); // #2599 TEST_CASE(sizeofsizeof); TEST_CASE(casting); @@ -239,6 +240,7 @@ private: TEST_CASE(simplifyTypedef78); // ticket #2568 TEST_CASE(simplifyTypedef79); // ticket #2348 TEST_CASE(simplifyTypedef80); // ticket #2587 + TEST_CASE(simplifyTypedef81); // ticket #2603 TEST_CASE(simplifyTypedefFunction1); TEST_CASE(simplifyTypedefFunction2); // ticket #1685 @@ -284,6 +286,7 @@ private: TEST_CASE(enum17); // ticket #2381 (duplicate enums) TEST_CASE(enum18); // #2466 (array with same name as enum constant) TEST_CASE(enum19); // ticket #2536 + TEST_CASE(enum20); // ticket #2600 // remove "std::" on some standard functions TEST_CASE(removestd); @@ -324,6 +327,8 @@ private: TEST_CASE(simplifyFunctionReturn); TEST_CASE(removeUnnecessaryQualification); + + TEST_CASE(simplifyIfNotNull); } std::string tok(const char code[], bool simplify = true) @@ -1418,6 +1423,15 @@ private: tok(code); } + void sizeof22() + { + // ticket #2599 segmentation fault + const char code[] = "sizeof\n"; + + // don't segfault + tok(code); + } + void sizeofsizeof() { @@ -4908,6 +4922,15 @@ private: ASSERT_EQUALS("", errout.str()); } + void simplifyTypedef81() // ticket #2603 segmentation fault + { + checkSimplifyTypedef("typedef\n"); + ASSERT_EQUALS("[test.cpp:1]: (error) syntax error\n", errout.str()); + + checkSimplifyTypedef("typedef constexpr\n"); + ASSERT_EQUALS("[test.cpp:1]: (error) syntax error\n", errout.str()); + } + void simplifyTypedefFunction1() { { @@ -6173,6 +6196,12 @@ private: ASSERT_EQUALS(";", tok(code, false)); } + void enum20() // ticket #2600 segmentation fault + { + const char code[] = "enum { const }\n"; + ASSERT_EQUALS(";", tok(code, false)); + } + void removestd() { ASSERT_EQUALS("; strcpy ( a , b ) ;", tok("; std::strcpy(a,b);")); @@ -6499,6 +6528,13 @@ private: ASSERT_EQUALS(expected, tok(code, false)); ASSERT_EQUALS("[test.cpp:1]: (portability) Extra qualification 'Fred::' unnecessary and considered an error by many compilers.\n", errout.str()); } + + void simplifyIfNotNull() // ticket # 2601 segmentation fault + { + const char code[] = "|| #if #define <="; + tok(code, false); + ASSERT_EQUALS("", errout.str()); + } }; REGISTER_TEST(TestSimplifyTokens) diff --git a/test/testunusedprivfunc.cpp b/test/testunusedprivfunc.cpp index 272df269f..ea2e2097d 100644 --- a/test/testunusedprivfunc.cpp +++ b/test/testunusedprivfunc.cpp @@ -39,6 +39,7 @@ private: TEST_CASE(test3); TEST_CASE(test4); TEST_CASE(test5); + TEST_CASE(test6); // ticket #2602 // [ 2236547 ] False positive --style unused function, called via pointer TEST_CASE(func_pointer1); @@ -225,6 +226,14 @@ private: ASSERT_EQUALS("", errout.str()); } + void test6() // ticket #2602 segmentation fault + { + check("class A {\n" + " A& operator=(const A&);\n" + "};\n"); + ASSERT_EQUALS("", errout.str()); + } +