Fixed #2127 (null pointer dereference after condition (SRD nr 522))
This commit is contained in:
parent
41a06a21d9
commit
026514db1a
|
@ -2534,6 +2534,69 @@ void CheckOther::nullPointerByDeRefAndChec()
|
|||
}
|
||||
}
|
||||
|
||||
void CheckOther::nullPointerByCheckAndDeRef()
|
||||
{
|
||||
// Check if pointer is NULL and then dereference it..
|
||||
for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next())
|
||||
{
|
||||
if (Token::Match(tok, "if ( ! %var% ) {"))
|
||||
{
|
||||
bool null = true;
|
||||
const unsigned int varid(tok->tokAt(3)->varId());
|
||||
unsigned int indentlevel = 1;
|
||||
for (const Token *tok2 = tok->tokAt(6); tok2; tok2 = tok2->next())
|
||||
{
|
||||
if (tok2->str() == "{")
|
||||
++indentlevel;
|
||||
else if (tok2->str() == "}")
|
||||
{
|
||||
if (indentlevel == 0)
|
||||
break;
|
||||
--indentlevel;
|
||||
if (null && indentlevel == 0)
|
||||
{
|
||||
// skip all "else" blocks because they are not executed in this execution path
|
||||
while (Token::Match(tok2, "} else {"))
|
||||
tok2 = tok2->tokAt(2)->link();
|
||||
null = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (Token::Match(tok2, "goto|return|continue|break|if"))
|
||||
{
|
||||
if (Token::Match(tok2, "return * %var%"))
|
||||
nullPointerError(tok2, tok->strAt(3));
|
||||
break;
|
||||
}
|
||||
|
||||
if (tok2->varId() == varid)
|
||||
{
|
||||
if (Token::Match(tok2->previous(), "[;{}=] %var% = 0 ;"))
|
||||
;
|
||||
|
||||
else if (Token::Match(tok2->tokAt(-2), "[;{}=+-/(,] * %var%"))
|
||||
nullPointerError(tok2, tok->strAt(3));
|
||||
|
||||
else if (!Token::simpleMatch(tok2->tokAt(-2), "& (") && Token::Match(tok2->next(), ". %var%"))
|
||||
nullPointerError(tok2, tok->strAt(3));
|
||||
|
||||
else if (Token::Match(tok2->previous(), "[;{}=+-/(,] %var% [ %any% ]"))
|
||||
nullPointerError(tok2, tok->strAt(3));
|
||||
|
||||
else if (Token::Match(tok2->previous(), "return %var% [ %any% ]"))
|
||||
nullPointerError(tok2, tok->strAt(3));
|
||||
|
||||
else if (Token::Match(tok2, "%var% ("))
|
||||
nullPointerError(tok2, tok->strAt(3));
|
||||
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CheckOther::nullPointer()
|
||||
{
|
||||
|
@ -2541,6 +2604,7 @@ void CheckOther::nullPointer()
|
|||
nullPointerLinkedList();
|
||||
nullPointerStructByDeRefAndChec();
|
||||
nullPointerByDeRefAndChec();
|
||||
nullPointerByCheckAndDeRef();
|
||||
}
|
||||
|
||||
/** Derefencing null constant (simplified token list) */
|
||||
|
|
|
@ -89,6 +89,9 @@ public:
|
|||
// New type of check: Check execution paths
|
||||
checkOther.executionPaths();
|
||||
checkOther.checkMisusedScopedObject();
|
||||
|
||||
// FIXME: I get a deadlock if I uncomment this:
|
||||
//nullPointerByCheckAndDeRef();
|
||||
}
|
||||
|
||||
|
||||
|
@ -324,6 +327,12 @@ private:
|
|||
*/
|
||||
void nullPointerByDeRefAndChec();
|
||||
|
||||
/**
|
||||
* @brief Does one part of the check for nullPointer().
|
||||
* Checking if pointer is NULL and then dereferencing it..
|
||||
*/
|
||||
void nullPointerByCheckAndDeRef();
|
||||
|
||||
/**
|
||||
* @brief Does one part of the check for nullPointer().
|
||||
* -# initialize pointer to 0
|
||||
|
|
|
@ -68,6 +68,7 @@ private:
|
|||
TEST_CASE(nullpointer7);
|
||||
TEST_CASE(nullpointer8);
|
||||
TEST_CASE(nullpointer9);
|
||||
TEST_CASE(nullpointer10); // check if pointer is null and then dereference it
|
||||
|
||||
TEST_CASE(uninitvar1);
|
||||
TEST_CASE(uninitvar_alloc); // data is allocated but not initialized
|
||||
|
@ -1148,6 +1149,25 @@ private:
|
|||
ASSERT_EQUALS("[test.cpp:4]: (error) Possible null pointer dereference: x\n", errout.str());
|
||||
}
|
||||
|
||||
// Check if pointer is null and the dereference it
|
||||
void nullpointer10()
|
||||
{
|
||||
checkNullPointer("void foo(char *p) {\n"
|
||||
" if (!p) {\n"
|
||||
" }\n"
|
||||
" *p = 0;\n"
|
||||
"}\n");
|
||||
ASSERT_EQUALS("[test.cpp:4]: (error) Possible null pointer dereference: p\n", errout.str());
|
||||
|
||||
checkNullPointer("void foo(abc *p) {\n"
|
||||
" if (!p) {\n"
|
||||
" }\n"
|
||||
" else if (!p->x) {\n"
|
||||
" }\n"
|
||||
"}\n");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
}
|
||||
|
||||
void checkUninitVar(const char code[])
|
||||
{
|
||||
// Tokenize..
|
||||
|
|
Loading…
Reference in New Issue