null pointers: detect when there are possible null pointer dereferencing when looping through a linked list both in inner and outer loops at the same time
This commit is contained in:
parent
228e926654
commit
2d9e4e1a73
|
@ -1011,6 +1011,75 @@ void CheckOther::nullPointer()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// looping through items in a linked list in a inner loop..
|
||||||
|
for (const Token *tok1 = _tokenizer->tokens(); tok1; tok1 = tok1->next())
|
||||||
|
{
|
||||||
|
// search for a "for" token..
|
||||||
|
if (!Token::simpleMatch(tok1, "for ("))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!Token::simpleMatch(tok1->next()->link(), ") {"))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// is there any dereferencing occuring in the for statement..
|
||||||
|
unsigned int parlevel2 = 1;
|
||||||
|
for (const Token *tok2 = tok1->tokAt(2); tok2; tok2 = tok2->next())
|
||||||
|
{
|
||||||
|
// Parantheses..
|
||||||
|
if (tok2->str() == "(")
|
||||||
|
++parlevel2;
|
||||||
|
else if (tok2->str() == ")")
|
||||||
|
{
|
||||||
|
if (parlevel2 <= 1)
|
||||||
|
break;
|
||||||
|
--parlevel2;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dereferencing a variable inside the "for" parantheses..
|
||||||
|
else if (Token::Match(tok2, "%var% . %var%"))
|
||||||
|
{
|
||||||
|
const unsigned int varid(tok2->varId());
|
||||||
|
if (varid == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Check usage of dereferenced variable in the loop..
|
||||||
|
unsigned int indentlevel3 = 0;
|
||||||
|
for (const Token *tok3 = tok1->next()->link(); tok3; tok3 = tok3->next())
|
||||||
|
{
|
||||||
|
if (tok3->str() == "{")
|
||||||
|
++indentlevel3;
|
||||||
|
else if (tok3->str() == "}")
|
||||||
|
{
|
||||||
|
if (indentlevel3 <= 1)
|
||||||
|
break;
|
||||||
|
--indentlevel3;
|
||||||
|
}
|
||||||
|
else if (Token::Match(tok3, "while ( %varid% &&|)", varid))
|
||||||
|
{
|
||||||
|
// Make sure there is a "break" to prevent segmentation faults..
|
||||||
|
unsigned int indentlevel4 = indentlevel3;
|
||||||
|
for (const Token *tok4 = tok3; tok4; tok4 = tok4->next())
|
||||||
|
{
|
||||||
|
if (tok4->str() == "{")
|
||||||
|
++indentlevel4;
|
||||||
|
else if (tok4->str() == "}")
|
||||||
|
{
|
||||||
|
if (indentlevel4 <= 1)
|
||||||
|
{
|
||||||
|
nullPointerError(tok1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
--indentlevel4;
|
||||||
|
}
|
||||||
|
else if (tok4->str() == "break")
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Dereferencing a struct pointer and then checking if it's NULL..
|
// Dereferencing a struct pointer and then checking if it's NULL..
|
||||||
for (const Token *tok1 = _tokenizer->tokens(); tok1; tok1 = tok1->next())
|
for (const Token *tok1 = _tokenizer->tokens(); tok1; tok1 = tok1->next())
|
||||||
{
|
{
|
||||||
|
|
|
@ -445,10 +445,7 @@ private:
|
||||||
" tok = tok->next();\n"
|
" tok = tok->next();\n"
|
||||||
" }\n"
|
" }\n"
|
||||||
"}\n");
|
"}\n");
|
||||||
// Actual result:
|
ASSERT_EQUALS("[test.cpp:3]: (error) Possible null pointer dereference\n", errout.str());
|
||||||
ASSERT_EQUALS("", errout.str());
|
|
||||||
// Expected (todo) result:
|
|
||||||
TODO_ASSERT_EQUALS("[test.cpp:3]: (error) Possible null pointer dereference\n", errout.str());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void nullpointer2()
|
void nullpointer2()
|
||||||
|
|
Loading…
Reference in New Issue