From 88e9a4ade65b55b8933f91ba11c7e8cfce6b47b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Wed, 26 May 2010 19:16:42 +0200 Subject: [PATCH] Fixed #1704 (false negative: null pointer dereference) --- lib/checkother.cpp | 40 +++++++++++++++++++++++++++------------- lib/checkother.h | 5 +++++ test/testother.cpp | 11 +++++++++++ 3 files changed, 43 insertions(+), 13 deletions(-) diff --git a/lib/checkother.cpp b/lib/checkother.cpp index 72177ba6c..24a6d445e 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -2188,7 +2188,34 @@ void CheckOther::nullPointer() nullPointerByDeRefAndChec(); } +/** Derefencing null constant (simplified token list) */ +void CheckOther::nullConstantDereference() +{ + for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next()) + { + if (tok->str() == "(" && Token::simpleMatch(tok->previous(), "sizeof")) + tok = tok->link(); + else if (Token::simpleMatch(tok, "exit ( )")) + { + while (tok && tok->str() != "}") + { + if (tok->str() == "{") + tok = tok->link(); + tok = tok->next(); + } + } + + else if (Token::simpleMatch(tok, "* 0")) + { + if (Token::Match(tok->previous(), "[;{}=+-/(,]") || + Token::Match(tok->previous(), "return|<<")) + { + nullPointerError(tok); + } + } + } +} /** * \brief parse a function call and extract information about variable usage @@ -2409,19 +2436,6 @@ private: bailOutVar(checks, tok.varId()); } - else if (Token::simpleMatch(&tok, "* 0")) - { - if (Token::Match(tok.previous(), "[;{}=+-/(,]") || - Token::Match(tok.previous(), "return|<<")) - { - CheckOther *checkOther = dynamic_cast(owner); - if (checkOther) - { - checkOther->nullPointerError(&tok); - } - } - } - else if (tok.str() == "delete") { const Token *ret = tok.next(); diff --git a/lib/checkother.h b/lib/checkother.h index fe844dceb..8ef424baf 100644 --- a/lib/checkother.h +++ b/lib/checkother.h @@ -80,6 +80,8 @@ public: checkOther.checkMathFunctions(); checkOther.checkFflushOnInputStream(); + checkOther.nullConstantDereference(); + // New type of check: Check execution paths checkOther.executionPaths(); } @@ -141,6 +143,9 @@ public: /** @brief possible null pointer dereference */ void nullPointer(); + /** @brief dereferencing null constant (after Tokenizer::simplifyKnownVariables) */ + void nullConstantDereference(); + /** @brief new type of check: check execution paths */ void executionPaths(); diff --git a/test/testother.cpp b/test/testother.cpp index b055fd1a0..e861ba823 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -702,6 +702,7 @@ private: checkOther.nullPointer(); tokenizer.simplifyTokenList(); + checkOther.nullConstantDereference(); checkOther.executionPaths(); } @@ -978,6 +979,7 @@ private: ASSERT_EQUALS("", errout.str()); } + // Execution paths.. void nullpointer6() { // errors.. @@ -1038,6 +1040,15 @@ private: "}\n"); ASSERT_EQUALS("[test.cpp:7]: (error) Possible null pointer dereference: c\n", errout.str()); + checkNullPointer("void f()\n" + "{\n" + " if (x) {\n" + " char *c = 0;\n" + " *c = 0;\n" + " }\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:5]: (error) Null pointer dereference\n", errout.str()); + // no false positive.. checkNullPointer("static void foo()\n" "{\n"