possible null pointer dereference after a while-loop
This commit is contained in:
parent
063f59c86c
commit
c0b608059a
|
@ -908,6 +908,60 @@ void CheckOther::returnPointerToStackData()
|
|||
}
|
||||
|
||||
|
||||
|
||||
void CheckOther::nullPointer()
|
||||
{
|
||||
// Locate insufficient null-pointer handling after loop
|
||||
for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next())
|
||||
{
|
||||
if (! Token::Match(tok, "while ( %var% )"))
|
||||
continue;
|
||||
|
||||
const unsigned int varid(tok->tokAt(2)->varId());
|
||||
if (varid == 0)
|
||||
continue;
|
||||
|
||||
// Locate the end of the while loop..
|
||||
const Token *tok2 = tok->tokAt(4);
|
||||
int indentlevel = 0;
|
||||
while (tok2)
|
||||
{
|
||||
if (tok2->str() == "{")
|
||||
++indentlevel;
|
||||
else if (tok2->str() == "}")
|
||||
{
|
||||
if (indentlevel <= 1)
|
||||
break;
|
||||
--indentlevel;
|
||||
}
|
||||
else if (indentlevel == 0 && tok2->str() == ";")
|
||||
break;
|
||||
tok2 = tok2->next();
|
||||
}
|
||||
|
||||
// Goto next token
|
||||
tok2 = tok2 ? tok2->next() : 0;
|
||||
|
||||
// Check if the variable is dereferenced..
|
||||
while (tok2)
|
||||
{
|
||||
if (tok2->str() == "{" || tok2->str() == "}")
|
||||
break;
|
||||
|
||||
if (tok2->varId() == varid)
|
||||
{
|
||||
if (tok2->next()->str() == "." || Token::Match(tok2->next(), "= %varid% .", varid))
|
||||
nullPointerError(tok2);
|
||||
break;
|
||||
}
|
||||
|
||||
tok2 = tok2->next();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void CheckOther::cstyleCastError(const Token *tok)
|
||||
{
|
||||
reportError(tok, "style", "cstyleCast", "C-style pointer casting");
|
||||
|
@ -992,3 +1046,8 @@ void CheckOther::returnLocalVariable(const Token *tok)
|
|||
{
|
||||
reportError(tok, "error", "returnLocalVariable", "Returning pointer to local array variable");
|
||||
}
|
||||
|
||||
void CheckOther::nullPointerError(const Token *tok)
|
||||
{
|
||||
reportError(tok, "error", "nullPointer", "Possible null pointer dereference");
|
||||
}
|
||||
|
|
|
@ -70,6 +70,7 @@ public:
|
|||
checkOther.strPlusChar();
|
||||
checkOther.returnPointerToStackData();
|
||||
checkOther.InvalidFunctionUsage();
|
||||
checkOther.nullPointer();
|
||||
}
|
||||
|
||||
// Casting
|
||||
|
@ -108,6 +109,9 @@ public:
|
|||
/** Returning pointer to local data */
|
||||
void returnPointerToStackData();
|
||||
|
||||
/** possible null pointer dereference */
|
||||
void nullPointer();
|
||||
|
||||
protected:
|
||||
void CheckVariableScope_LookupVar(const Token *tok1, const char varname[]);
|
||||
|
||||
|
@ -135,6 +139,7 @@ private:
|
|||
void conditionAlwaysTrueFalse(const Token *tok, const std::string &truefalse);
|
||||
void strPlusChar(const Token *tok);
|
||||
void returnLocalVariable(const Token *tok);
|
||||
void nullPointerError(const Token *tok);
|
||||
|
||||
void getErrorMessages()
|
||||
{
|
||||
|
@ -155,6 +160,7 @@ private:
|
|||
conditionAlwaysTrueFalse(0, "true/false");
|
||||
strPlusChar(0);
|
||||
returnLocalVariable(0);
|
||||
nullPointerError(0);
|
||||
}
|
||||
|
||||
};
|
||||
|
|
|
@ -53,6 +53,8 @@ private:
|
|||
|
||||
TEST_CASE(varScope1);
|
||||
TEST_CASE(varScope2);
|
||||
|
||||
TEST_CASE(nullpointer1);
|
||||
}
|
||||
|
||||
void check(const char code[])
|
||||
|
@ -71,6 +73,9 @@ private:
|
|||
checkOther.WarningRedundantCode();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void delete1()
|
||||
{
|
||||
check("void foo()\n"
|
||||
|
@ -326,6 +331,38 @@ private:
|
|||
"}\n");
|
||||
ASSERT_EQUALS(std::string(""), errout.str());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void checkNullPointer(const char code[])
|
||||
{
|
||||
// Tokenize..
|
||||
Tokenizer tokenizer;
|
||||
std::istringstream istr(code);
|
||||
tokenizer.tokenize(istr, "test.cpp");
|
||||
tokenizer.setVarId();
|
||||
|
||||
// Clear the error buffer..
|
||||
errout.str("");
|
||||
|
||||
// Check for redundant code..
|
||||
Settings settings;
|
||||
settings._checkCodingStyle = true;
|
||||
CheckOther checkOther(&tokenizer, &settings, this);
|
||||
checkOther.nullPointer();
|
||||
}
|
||||
|
||||
|
||||
void nullpointer1()
|
||||
{
|
||||
checkNullPointer("int foo(const Token *tok)\n"
|
||||
"{\n"
|
||||
" while (tok);\n"
|
||||
" tok = tok->next();\n"
|
||||
"}\n");
|
||||
ASSERT_EQUALS(std::string("[test.cpp:4]: (error) Possible null pointer dereference\n"), errout.str());
|
||||
}
|
||||
};
|
||||
|
||||
REGISTER_TEST(TestOther)
|
||||
|
|
Loading…
Reference in New Issue