From 6ec4497919363ca3a81b61ce8121a9b48e46fe63 Mon Sep 17 00:00:00 2001 From: Raphael Geissert Date: Thu, 6 Jan 2011 11:31:58 +0100 Subject: [PATCH] [PATCH] Check for calls to memset() where 0 bytes are to be filled Inspired by Silvio Cesare's work --- lib/checkother.cpp | 20 ++++++++++++++++++++ lib/checkother.h | 6 ++++++ test/testother.cpp | 20 ++++++++++++++++++++ 3 files changed, 46 insertions(+) diff --git a/lib/checkother.cpp b/lib/checkother.cpp index d7026ae29..cf3529de2 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -520,6 +520,19 @@ void CheckOther::checkUnsignedDivision() } } } + +//--------------------------------------------------------------------------- +// memset(p, y, 0 /* bytes to fill */) <- 2nd and 3rd arguments inverted +//--------------------------------------------------------------------------- +void CheckOther::checkMemsetZeroBytes() +{ + const Token *tok = _tokenizer->tokens(); + while (tok && ((tok = Token::findmatch(tok, "memset ( %var% , %num% , 0 )")) != NULL)) + { + memsetZeroBytesError(tok, tok->strAt(2)); + tok = tok->tokAt(8); + } +} //--------------------------------------------------------------------------- @@ -2803,3 +2816,10 @@ void CheckOther::catchExceptionByValueError(const Token *tok) "The exception is caught as a value. It could be caught " "as a (const) reference which is usually recommended in C++."); } + +void CheckOther::memsetZeroBytesError(const Token *tok, const std::string &varname) +{ + reportError(tok, Severity::warning, + "memsetZeroBytes", "memset() called to fill 0 bytes of \"" + varname + "\"" + ". Second and third arguments might be inverted."); +} diff --git a/lib/checkother.h b/lib/checkother.h index 4af6d528b..ee6909cdb 100644 --- a/lib/checkother.h +++ b/lib/checkother.h @@ -83,6 +83,7 @@ public: checkOther.checkIncorrectLogicOperator(); checkOther.checkMisusedScopedObject(); checkOther.checkCatchExceptionByValue(); + checkOther.checkMemsetZeroBytes(); } /** @brief Are there C-style pointer casts in a c++ file? */ @@ -166,6 +167,9 @@ public: /** @brief %Check for exceptions that are caught by value instead of by reference */ void checkCatchExceptionByValue(); + /** @brief %Check for filling zero bytes with memset() */ + void checkMemsetZeroBytes(); + // Error messages.. void cstyleCastError(const Token *tok); void dangerousUsageStrtolError(const Token *tok); @@ -188,6 +192,7 @@ public: void incorrectLogicOperatorError(const Token *tok); void misusedScopeObjectError(const Token *tok, const std::string &varname); void catchExceptionByValueError(const Token *tok); + void memsetZeroBytesError(const Token *tok, const std::string &varname); void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) { @@ -224,6 +229,7 @@ public: c.unreadVariableError(0, "varname"); c.unassignedVariableError(0, "varname"); c.catchExceptionByValueError(0); + c.memsetZeroBytesError(0, "varname"); } std::string name() const diff --git a/test/testother.cpp b/test/testother.cpp index 01f23d9aa..010ab319f 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -94,6 +94,8 @@ private: TEST_CASE(assignmentInAssert); TEST_CASE(incorrectLogicOperator); TEST_CASE(catchExceptionByValue); + + TEST_CASE(memsetZeroBytes); } void check(const char code[], const char *filename = NULL) @@ -127,6 +129,7 @@ private: checkOther.checkMisusedScopedObject(); checkOther.checkIncorrectLogicOperator(); checkOther.checkCatchExceptionByValue(); + checkOther.checkMemsetZeroBytes(); } @@ -1614,6 +1617,23 @@ private: ); ASSERT_EQUALS("", errout.str()); } + + void memsetZeroBytes() + { + check("void f() {\n" + " memset(p, 10, 0)\n" + "}\n" + ); + ASSERT_EQUALS("[test.cpp:2]: (warning) memset() called to fill 0" + " bytes of \"p\". Second and third arguments might be inverted.\n", errout.str()); + + check("void f() {\n" + " memset(p, sizeof(p), 0)\n" + "}\n" + ); + TODO_ASSERT_EQUALS("[test.cpp:2]: (warning) memset() called to fill 0" + " bytes of \"p\". Second and third arguments might be inverted.\n", errout.str()); + } }; REGISTER_TEST(TestOther)