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:
Daniel Marjamäki 2009-07-31 10:49:43 +02:00
parent 228e926654
commit 2d9e4e1a73
2 changed files with 70 additions and 4 deletions

View File

@ -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())
{ {

View File

@ -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()