CWE mapping of unsafeClassCanLeak, zerodivcond, invalidPointerCast, redundantCopy, redundantAssignment, comparisonFunctionIsAlwaysTrueOrFalse, checkCastIntToCharAndBack, cstyleCast, passedByValue, clarifyCondition, exceptThrowInDestructor, exceptDeallocThrow, exceptRethrowCopy, catchExceptionByValue, fflushOnInputStream, seekOnAppendedFile, publicAllocationError

CWE mapping of unsafeClassCanLeak, zerodivcond, invalidPointerCast, redundantCopy, redundantAssignment, comparisonFunctionIsAlwaysTrueOrFalse, checkCastIntToCharAndBack, cstyleCast, passedByValue, clarifyCondition, exceptThrowInDestructor, exceptDeallocThrow, exceptRethrowCopy, catchExceptionByValue, fflushOnInputStream, seekOnAppendedFile, publicAllocationError
This commit is contained in:
Roberto Martelloni 2016-04-12 18:29:40 +01:00 committed by PKEuS
parent 529c853d84
commit e89cd1b8a4
4 changed files with 36 additions and 21 deletions

View File

@ -24,11 +24,14 @@
#include "config.h" #include "config.h"
#include "check.h" #include "check.h"
// CWE ID used:
static const struct CWE CWE398(398U); // Indicator of Poor Code Quality
/// @addtogroup Checks /// @addtogroup Checks
/// @{ /// @{
/** /**
* @brief %Check exception safety (exceptions shouldn't cause leaks nor corrupt data) * @brief %Check exception safety (exceptions shouldn't cause leaks nor corrupt data)
* *
@ -87,30 +90,30 @@ private:
"Class " + className + " is not safe, destructor throws exception\n" "Class " + className + " is not safe, destructor throws exception\n"
"The class " + className + " is not safe because its destructor " "The class " + className + " is not safe because its destructor "
"throws an exception. If " + className + " is used and an exception " "throws an exception. If " + className + " is used and an exception "
"is thrown that is caught in an outer scope the program will terminate."); "is thrown that is caught in an outer scope the program will terminate.", CWE398, false);
} }
void deallocThrowError(const Token * const tok, const std::string &varname) { void deallocThrowError(const Token * const tok, const std::string &varname) {
reportError(tok, Severity::warning, "exceptDeallocThrow", "Exception thrown in invalid state, '" + reportError(tok, Severity::warning, "exceptDeallocThrow", "Exception thrown in invalid state, '" +
varname + "' points at deallocated memory."); varname + "' points at deallocated memory.", CWE398, false);
} }
void rethrowCopyError(const Token * const tok, const std::string &varname) { void rethrowCopyError(const Token * const tok, const std::string &varname) {
reportError(tok, Severity::style, "exceptRethrowCopy", reportError(tok, Severity::style, "exceptRethrowCopy",
"Throwing a copy of the caught exception instead of rethrowing the original exception.\n" "Throwing a copy of the caught exception instead of rethrowing the original exception.\n"
"Rethrowing an exception with 'throw " + varname + ";' creates an unnecessary copy of '" + varname + "'. " "Rethrowing an exception with 'throw " + varname + ";' creates an unnecessary copy of '" + varname + "'. "
"To rethrow the caught exception without unnecessary copying or slicing, use a bare 'throw;'."); "To rethrow the caught exception without unnecessary copying or slicing, use a bare 'throw;'.", CWE398, false);
} }
void catchExceptionByValueError(const Token *tok) { void catchExceptionByValueError(const Token *tok) {
reportError(tok, Severity::style, reportError(tok, Severity::style,
"catchExceptionByValue", "Exception should be caught by reference.\n" "catchExceptionByValue", "Exception should be caught by reference.\n"
"The exception is caught by value. It could be caught " "The exception is caught by 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++.", CWE398, false);
} }
void noexceptThrowError(const Token * const tok) { void noexceptThrowError(const Token * const tok) {
reportError(tok, Severity::error, "throwInNoexceptFunction", "Exception thrown in function declared not to throw exceptions."); reportError(tok, Severity::error, "throwInNoexceptFunction", "Exception thrown in function declared not to throw exceptions.", CWE398, false);
} }
/** Missing exception specification */ /** Missing exception specification */

View File

@ -33,6 +33,8 @@ namespace {
CheckIO instance; CheckIO instance;
} }
// CVE ID used:
static const CWE CWE398(398U); // Indicator of Poor Code Quality
static const CWE CWE664(664U); static const CWE CWE664(664U);
static const CWE CWE685(685U); static const CWE CWE685(685U);
static const CWE CWE687(687U); static const CWE CWE687(687U);
@ -333,7 +335,7 @@ void CheckIO::checkFileUsage()
void CheckIO::fflushOnInputStreamError(const Token *tok, const std::string &varname) void CheckIO::fflushOnInputStreamError(const Token *tok, const std::string &varname)
{ {
reportError(tok, Severity::portability, reportError(tok, Severity::portability,
"fflushOnInputStream", "fflush() called on input stream '" + varname + "' may result in undefined behaviour on non-linux systems."); "fflushOnInputStream", "fflush() called on input stream '" + varname + "' may result in undefined behaviour on non-linux systems.", CWE398, false);
} }
void CheckIO::ioWithoutPositioningError(const Token *tok) void CheckIO::ioWithoutPositioningError(const Token *tok)
@ -364,7 +366,7 @@ void CheckIO::useClosedFileError(const Token *tok)
void CheckIO::seekOnAppendedFileError(const Token *tok) void CheckIO::seekOnAppendedFileError(const Token *tok)
{ {
reportError(tok, Severity::warning, reportError(tok, Severity::warning,
"seekOnAppendedFile", "Repositioning operation performed on a file opened in append mode has no effect."); "seekOnAppendedFile", "Repositioning operation performed on a file opened in append mode has no effect.", CWE398, false);
} }

View File

@ -38,6 +38,8 @@ namespace {
CheckMemoryLeakNoVar instance4; CheckMemoryLeakNoVar instance4;
} }
// CWE ID used:
static const CWE CWE398(398U);
static const CWE CWE771(771U); static const CWE CWE771(771U);
static const CWE CWE772(772U); static const CWE CWE772(772U);
@ -2342,7 +2344,7 @@ void CheckMemoryLeakInClass::unsafeClassError(const Token *tok, const std::strin
reportError(tok, Severity::style, "unsafeClassCanLeak", reportError(tok, Severity::style, "unsafeClassCanLeak",
"Class '" + classname + "' is unsafe, '" + varname + "' can leak by wrong usage.\n" "Class '" + classname + "' is unsafe, '" + varname + "' can leak by wrong usage.\n"
"The class '" + classname + "' is unsafe, wrong usage can cause memory/resource leaks for '" + varname + "'. This can for instance be fixed by adding proper cleanup in the destructor."); "The class '" + classname + "' is unsafe, wrong usage can cause memory/resource leaks for '" + varname + "'. This can for instance be fixed by adding proper cleanup in the destructor.", CWE398, false);
} }
@ -2380,7 +2382,7 @@ void CheckMemoryLeakInClass::checkPublicFunctions(const Scope *scope, const Toke
void CheckMemoryLeakInClass::publicAllocationError(const Token *tok, const std::string &varname) void CheckMemoryLeakInClass::publicAllocationError(const Token *tok, const std::string &varname)
{ {
reportError(tok, Severity::warning, "publicAllocationError", "Possible leak in public function. The pointer '" + varname + "' is not deallocated before it is allocated."); reportError(tok, Severity::warning, "publicAllocationError", "Possible leak in public function. The pointer '" + varname + "' is not deallocated before it is allocated.", CWE398, false);
} }

View File

@ -33,9 +33,15 @@ namespace {
CheckOther instance; CheckOther instance;
} }
static const struct CWE CWE197(197U); // Numeric Truncation Error
static const struct CWE CWE369(369U); static const struct CWE CWE369(369U);
static const struct CWE CWE398(398U); // Indicator of Poor Code Quality
static const struct CWE CWE563(563U); static const struct CWE CWE563(563U);
static const struct CWE CWE570(570U); // Expression is Always False
static const struct CWE CWE571(571U); // Expression is Always True
static const struct CWE CWE686(686U); static const struct CWE CWE686(686U);
static const struct CWE CWE704(704U); // Incorrect Type Conversion or Cast
static const struct CWE CWE758(758U); static const struct CWE CWE758(758U);
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
@ -111,7 +117,7 @@ void CheckOther::checkCastIntToCharAndBackError(const Token *tok, const std::str
" When "+ strFunctionName +"() returns EOF this value is truncated. Comparing the char " " When "+ strFunctionName +"() returns EOF this value is truncated. Comparing the char "
"variable with EOF can have unexpected results. For instance a loop \"while (EOF != (c = "+ strFunctionName +"());\" " "variable with EOF can have unexpected results. For instance a loop \"while (EOF != (c = "+ strFunctionName +"());\" "
"loops forever on some compilers/platforms and on other compilers/platforms it will stop " "loops forever on some compilers/platforms and on other compilers/platforms it will stop "
"when the file contains a matching character." "when the file contains a matching character.", CWE197, false
); );
} }
@ -284,7 +290,7 @@ void CheckOther::cstyleCastError(const Token *tok)
"C-style pointer casting detected. C++ offers four different kinds of casts as replacements: " "C-style pointer casting detected. C++ offers four different kinds of casts as replacements: "
"static_cast, const_cast, dynamic_cast and reinterpret_cast. A C-style cast could evaluate to " "static_cast, const_cast, dynamic_cast and reinterpret_cast. A C-style cast could evaluate to "
"any of those automatically, thus it is considered safer if the programmer explicitly states " "any of those automatically, thus it is considered safer if the programmer explicitly states "
"which kind of cast is expected. See also: https://www.securecoding.cert.org/confluence/display/cplusplus/EXP05-CPP.+Do+not+use+C-style+casts."); "which kind of cast is expected. See also: https://www.securecoding.cert.org/confluence/display/cplusplus/EXP05-CPP.+Do+not+use+C-style+casts.", CWE398, false);
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@ -338,11 +344,11 @@ void CheckOther::invalidPointerCastError(const Token* tok, const std::string& fr
{ {
if (to == "integer") { // If we cast something to int*, this can be useful to play with its binary data representation if (to == "integer") { // If we cast something to int*, this can be useful to play with its binary data representation
if (!inconclusive) if (!inconclusive)
reportError(tok, Severity::portability, "invalidPointerCast", "Casting from " + from + "* to integer* is not portable due to different binary data representations on different platforms."); reportError(tok, Severity::portability, "invalidPointerCast", "Casting from " + from + "* to integer* is not portable due to different binary data representations on different platforms.", CWE704, false);
else else
reportError(tok, Severity::portability, "invalidPointerCast", "Casting from " + from + "* to char* is not portable due to different binary data representations on different platforms.", CWE(0U), true); reportError(tok, Severity::portability, "invalidPointerCast", "Casting from " + from + "* to char* is not portable due to different binary data representations on different platforms.", CWE704, true);
} else } else
reportError(tok, Severity::portability, "invalidPointerCast", "Casting between " + from + "* and " + to + "* which have an incompatible binary data representation."); reportError(tok, Severity::portability, "invalidPointerCast", "Casting between " + from + "* and " + to + "* which have an incompatible binary data representation.", CWE704, false);
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@ -598,7 +604,7 @@ void CheckOther::redundantCopyError(const Token *tok1, const Token* tok2, const
{ {
const std::list<const Token *> callstack = make_container< std::list<const Token *> >() << tok1 << tok2; const std::list<const Token *> callstack = make_container< std::list<const Token *> >() << tok1 << tok2;
reportError(callstack, Severity::performance, "redundantCopy", reportError(callstack, Severity::performance, "redundantCopy",
"Buffer '" + var + "' is being written before its old content has been used."); "Buffer '" + var + "' is being written before its old content has been used.", CWE398, false);
} }
void CheckOther::redundantCopyInSwitchError(const Token *tok1, const Token* tok2, const std::string &var) void CheckOther::redundantCopyInSwitchError(const Token *tok1, const Token* tok2, const std::string &var)
@ -614,10 +620,10 @@ void CheckOther::redundantAssignmentError(const Token *tok1, const Token* tok2,
if (inconclusive) if (inconclusive)
reportError(callstack, Severity::style, "redundantAssignment", reportError(callstack, Severity::style, "redundantAssignment",
"Variable '" + var + "' is reassigned a value before the old one has been used if variable is no semaphore variable.\n" "Variable '" + var + "' is reassigned a value before the old one has been used if variable is no semaphore variable.\n"
"Variable '" + var + "' is reassigned a value before the old one has been used. Make sure that this variable is not used like a semaphore in a threading environment before simplifying this code.", CWE(0U), true); "Variable '" + var + "' is reassigned a value before the old one has been used. Make sure that this variable is not used like a semaphore in a threading environment before simplifying this code.", CWE398, true);
else else
reportError(callstack, Severity::style, "redundantAssignment", reportError(callstack, Severity::style, "redundantAssignment",
"Variable '" + var + "' is reassigned a value before the old one has been used."); "Variable '" + var + "' is reassigned a value before the old one has been used.", CWE398, false);
} }
void CheckOther::redundantAssignmentInSwitchError(const Token *tok1, const Token* tok2, const std::string &var) void CheckOther::redundantAssignmentInSwitchError(const Token *tok1, const Token* tok2, const std::string &var)
@ -1408,7 +1414,7 @@ void CheckOther::passedByValueError(const Token *tok, const std::string &parname
reportError(tok, Severity::performance, "passedByValue", reportError(tok, Severity::performance, "passedByValue",
"Function parameter '" + parname + "' should be passed by reference.\n" "Function parameter '" + parname + "' should be passed by reference.\n"
"Parameter '" + parname + "' is passed by value. It could be passed " "Parameter '" + parname + "' is passed by value. It could be passed "
"as a (const) reference which is usually faster and recommended in C++."); "as a (const) reference which is usually faster and recommended in C++.", CWE398, false);
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@ -1624,7 +1630,7 @@ void CheckOther::zerodivcondError(const Token *tokcond, const Token *tokdiv, boo
callstack.push_back(tokdiv); callstack.push_back(tokdiv);
} }
const std::string linenr(MathLib::toString(tokdiv ? tokdiv->linenr() : 0)); const std::string linenr(MathLib::toString(tokdiv ? tokdiv->linenr() : 0));
reportError(callstack, Severity::warning, "zerodivcond", ValueFlow::eitherTheConditionIsRedundant(tokcond) + " or there is division by zero at line " + linenr + ".", CWE(0U), inconclusive); reportError(callstack, Severity::warning, "zerodivcond", ValueFlow::eitherTheConditionIsRedundant(tokcond) + " or there is division by zero at line " + linenr + ".", CWE369, inconclusive);
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@ -2001,10 +2007,12 @@ void CheckOther::checkComparisonFunctionIsAlwaysTrueOrFalse()
void CheckOther::checkComparisonFunctionIsAlwaysTrueOrFalseError(const Token* tok, const std::string &functionName, const std::string &varName, const bool result) void CheckOther::checkComparisonFunctionIsAlwaysTrueOrFalseError(const Token* tok, const std::string &functionName, const std::string &varName, const bool result)
{ {
const std::string strResult = result ? "true" : "false"; const std::string strResult = result ? "true" : "false";
const struct CWE cweResult = result ? CWE571 : CWE570;
reportError(tok, Severity::warning, "comparisonFunctionIsAlwaysTrueOrFalse", reportError(tok, Severity::warning, "comparisonFunctionIsAlwaysTrueOrFalse",
"Comparison of two identical variables with " + functionName + "(" + varName + "," + varName + ") always evaluates to " + strResult + ".\n" "Comparison of two identical variables with " + functionName + "(" + varName + "," + varName + ") always evaluates to " + strResult + ".\n"
"The function " + functionName + " is designed to compare two variables. Calling this function with one variable (" + varName + ") " "The function " + functionName + " is designed to compare two variables. Calling this function with one variable (" + varName + ") "
"for both parameters leads to a statement which is always " + strResult + "."); "for both parameters leads to a statement which is always " + strResult + ".", cweResult, false);
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------