[PATCH] Check for calls to memset() where 0 bytes are to be filled

Inspired by Silvio Cesare's work
This commit is contained in:
Raphael Geissert 2011-01-06 11:31:58 +01:00 committed by Daniel Marjamäki
parent 1152dc78f0
commit 6ec4497919
3 changed files with 46 additions and 0 deletions

View File

@ -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 " "The exception is caught as a value. It could be caught "
"as a (const) reference which is usually recommended in C++."); "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.");
}

View File

@ -83,6 +83,7 @@ public:
checkOther.checkIncorrectLogicOperator(); checkOther.checkIncorrectLogicOperator();
checkOther.checkMisusedScopedObject(); checkOther.checkMisusedScopedObject();
checkOther.checkCatchExceptionByValue(); checkOther.checkCatchExceptionByValue();
checkOther.checkMemsetZeroBytes();
} }
/** @brief Are there C-style pointer casts in a c++ file? */ /** @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 */ /** @brief %Check for exceptions that are caught by value instead of by reference */
void checkCatchExceptionByValue(); void checkCatchExceptionByValue();
/** @brief %Check for filling zero bytes with memset() */
void checkMemsetZeroBytes();
// Error messages.. // Error messages..
void cstyleCastError(const Token *tok); void cstyleCastError(const Token *tok);
void dangerousUsageStrtolError(const Token *tok); void dangerousUsageStrtolError(const Token *tok);
@ -188,6 +192,7 @@ public:
void incorrectLogicOperatorError(const Token *tok); void incorrectLogicOperatorError(const Token *tok);
void misusedScopeObjectError(const Token *tok, const std::string &varname); void misusedScopeObjectError(const Token *tok, const std::string &varname);
void catchExceptionByValueError(const Token *tok); void catchExceptionByValueError(const Token *tok);
void memsetZeroBytesError(const Token *tok, const std::string &varname);
void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings)
{ {
@ -224,6 +229,7 @@ public:
c.unreadVariableError(0, "varname"); c.unreadVariableError(0, "varname");
c.unassignedVariableError(0, "varname"); c.unassignedVariableError(0, "varname");
c.catchExceptionByValueError(0); c.catchExceptionByValueError(0);
c.memsetZeroBytesError(0, "varname");
} }
std::string name() const std::string name() const

View File

@ -94,6 +94,8 @@ private:
TEST_CASE(assignmentInAssert); TEST_CASE(assignmentInAssert);
TEST_CASE(incorrectLogicOperator); TEST_CASE(incorrectLogicOperator);
TEST_CASE(catchExceptionByValue); TEST_CASE(catchExceptionByValue);
TEST_CASE(memsetZeroBytes);
} }
void check(const char code[], const char *filename = NULL) void check(const char code[], const char *filename = NULL)
@ -127,6 +129,7 @@ private:
checkOther.checkMisusedScopedObject(); checkOther.checkMisusedScopedObject();
checkOther.checkIncorrectLogicOperator(); checkOther.checkIncorrectLogicOperator();
checkOther.checkCatchExceptionByValue(); checkOther.checkCatchExceptionByValue();
checkOther.checkMemsetZeroBytes();
} }
@ -1614,6 +1617,23 @@ private:
); );
ASSERT_EQUALS("", errout.str()); 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) REGISTER_TEST(TestOther)