[PATCH] Check for calls to memset() where 0 bytes are to be filled
Inspired by Silvio Cesare's work
This commit is contained in:
parent
1152dc78f0
commit
6ec4497919
|
@ -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.");
|
||||||
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
Loading…
Reference in New Issue