Partial fix for #6656 (Allow that CWE is mapped for error message)

This commit is contained in:
Daniel Marjamäki 2015-04-25 17:48:11 +02:00
parent ad6db2ba81
commit 88f59ad7e8
17 changed files with 107 additions and 77 deletions

View File

@ -109,15 +109,28 @@ protected:
/** report an error */ /** report an error */
template<typename T, typename U> template<typename T, typename U>
void reportError(const Token *tok, const Severity::SeverityType severity, const T id, const U msg, bool inconclusive = false) { void reportError(const Token *tok, const Severity::SeverityType severity, const T id, const U msg) {
std::list<const Token *> callstack(1, tok); reportError(tok, severity, id, msg, 0U, false);
reportError(callstack, severity, id, msg, inconclusive);
} }
/** report an error */ /** report an error */
template<typename T, typename U> template<typename T, typename U>
void reportError(const std::list<const Token *> &callstack, Severity::SeverityType severity, const T id, const U msg, bool inconclusive = false) { void reportError(const Token *tok, const Severity::SeverityType severity, const T id, const U msg, unsigned int cwe, bool inconclusive) {
std::list<const Token *> callstack(1, tok);
reportError(callstack, severity, id, msg, cwe, inconclusive);
}
/** report an error */
template<typename T, typename U>
void reportError(const std::list<const Token *> &callstack, Severity::SeverityType severity, const T id, const U msg) {
reportError(callstack, severity, id, msg, 0U, false);
}
/** report an error */
template<typename T, typename U>
void reportError(const std::list<const Token *> &callstack, Severity::SeverityType severity, const T id, const U msg, unsigned int cwe, bool inconclusive) {
ErrorLogger::ErrorMessage errmsg(callstack, _tokenizer?&_tokenizer->list:0, severity, id, msg, inconclusive); ErrorLogger::ErrorMessage errmsg(callstack, _tokenizer?&_tokenizer->list:0, severity, id, msg, inconclusive);
errmsg._cwe = cwe;
if (_errorLogger) if (_errorLogger)
_errorLogger->reportErr(errmsg); _errorLogger->reportErr(errmsg);
else else

View File

@ -268,7 +268,9 @@ void CheckAutoVariables::errorAutoVariableAssignment(const Token *tok, bool inco
"Function parameter is assigned the address of a local auto-variable. " "Function parameter is assigned the address of a local auto-variable. "
"Local auto-variables are reserved from the stack which is freed when " "Local auto-variables are reserved from the stack which is freed when "
"the function ends. The address is invalid after the function ends and it " "the function ends. The address is invalid after the function ends and it "
"might 'leak' from the function through the parameter.", true); "might 'leak' from the function through the parameter.",
0U,
true);
} }
} }

View File

@ -105,7 +105,9 @@ void CheckBool::checkBitwiseOnBoolean()
void CheckBool::bitwiseOnBooleanError(const Token *tok, const std::string &varname, const std::string &op) void CheckBool::bitwiseOnBooleanError(const Token *tok, const std::string &varname, const std::string &op)
{ {
reportError(tok, Severity::style, "bitwiseOnBoolean", reportError(tok, Severity::style, "bitwiseOnBoolean",
"Boolean variable '" + varname + "' is used in bitwise operation. Did you mean '" + op + "'?", true); "Boolean variable '" + varname + "' is used in bitwise operation. Did you mean '" + op + "'?",
0U,
true);
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------

View File

@ -91,7 +91,7 @@ void CheckBufferOverrun::arrayIndexOutOfBoundsError(const Token *tok, const Arra
std::list<const Token *> callstack; std::list<const Token *> callstack;
callstack.push_back(tok); callstack.push_back(tok);
callstack.push_back(condition); callstack.push_back(condition);
reportError(callstack, Severity::warning, "arrayIndexOutOfBoundsCond", errmsg.str()); reportError(callstack, Severity::warning, "arrayIndexOutOfBoundsCond", errmsg.str(), 0U, false);
} else { } else {
reportError(tok, Severity::error, "arrayIndexOutOfBounds", errmsg.str()); reportError(tok, Severity::error, "arrayIndexOutOfBounds", errmsg.str());
} }
@ -101,7 +101,7 @@ void CheckBufferOverrun::arrayIndexOutOfBoundsError(const std::list<const Token
{ {
std::ostringstream oss; std::ostringstream oss;
makeArrayIndexOutOfBoundsError(oss, arrayInfo, index); makeArrayIndexOutOfBoundsError(oss, arrayInfo, index);
reportError(callstack, Severity::error, "arrayIndexOutOfBounds", oss.str()); reportError(callstack, Severity::error, "arrayIndexOutOfBounds", oss.str(), 0U, false);
} }
static std::string bufferOverrunMessage(std::string varnames) static std::string bufferOverrunMessage(std::string varnames)
@ -125,7 +125,7 @@ void CheckBufferOverrun::bufferOverrunError(const Token *tok, const std::string
void CheckBufferOverrun::bufferOverrunError(const std::list<const Token *> &callstack, const std::string &varnames) void CheckBufferOverrun::bufferOverrunError(const std::list<const Token *> &callstack, const std::string &varnames)
{ {
reportError(callstack, Severity::error, "bufferAccessOutOfBounds", bufferOverrunMessage(varnames)); reportError(callstack, Severity::error, "bufferAccessOutOfBounds", bufferOverrunMessage(varnames), 0U, false);
} }
void CheckBufferOverrun::possibleBufferOverrunError(const Token *tok, const std::string &src, const std::string &dst, bool cat) void CheckBufferOverrun::possibleBufferOverrunError(const Token *tok, const std::string &src, const std::string &dst, bool cat)
@ -207,7 +207,7 @@ void CheckBufferOverrun::terminateStrncpyError(const Token *tok, const std::stri
"The buffer '" + varname + "' may not be null-terminated after the call to strncpy().\n" "The buffer '" + varname + "' may not be null-terminated after the call to strncpy().\n"
"If the source string's size fits or exceeds the given size, strncpy() does not add a " "If the source string's size fits or exceeds the given size, strncpy() does not add a "
"zero at the end of the buffer. This causes bugs later in the code if the code " "zero at the end of the buffer. This causes bugs later in the code if the code "
"assumes buffer is null-terminated.", true); "assumes buffer is null-terminated.", 0U, true);
} }
void CheckBufferOverrun::cmdLineArgsError(const Token *tok) void CheckBufferOverrun::cmdLineArgsError(const Token *tok)
@ -221,7 +221,7 @@ void CheckBufferOverrun::bufferNotZeroTerminatedError(const Token *tok, const st
"The buffer '" + varname + "' is not null-terminated after the call to " + function + "(). " "The buffer '" + varname + "' is not null-terminated after the call to " + function + "(). "
"This will cause bugs later in the code if the code assumes the buffer is null-terminated."; "This will cause bugs later in the code if the code assumes the buffer is null-terminated.";
reportError(tok, Severity::warning, "bufferNotZeroTerminated", errmsg, true); reportError(tok, Severity::warning, "bufferNotZeroTerminated", errmsg, 0U, true);
} }
void CheckBufferOverrun::argumentSizeError(const Token *tok, const std::string &functionName, const std::string &varname) void CheckBufferOverrun::argumentSizeError(const Token *tok, const std::string &functionName, const std::string &varname)
@ -1613,7 +1613,7 @@ void CheckBufferOverrun::negativeIndexError(const Token *tok, const ValueFlow::V
ostr << "Array index " << index.intvalue << " is out of bounds."; ostr << "Array index " << index.intvalue << " is out of bounds.";
if (index.condition) if (index.condition)
ostr << " Otherwise there is useless condition at line " << index.condition->linenr() << "."; ostr << " Otherwise there is useless condition at line " << index.condition->linenr() << ".";
reportError(tok, index.condition ? Severity::warning : Severity::error, "negativeIndex", ostr.str(), index.inconclusive); reportError(tok, index.condition ? Severity::warning : Severity::error, "negativeIndex", ostr.str(), 0U, index.inconclusive);
} }
CheckBufferOverrun::ArrayInfo::ArrayInfo() CheckBufferOverrun::ArrayInfo::ArrayInfo()

View File

@ -784,12 +784,12 @@ void CheckClass::noExplicitCopyMoveConstructorError(const Token *tok, const std:
void CheckClass::uninitVarError(const Token *tok, const std::string &classname, const std::string &varname, bool inconclusive) void CheckClass::uninitVarError(const Token *tok, const std::string &classname, const std::string &varname, bool inconclusive)
{ {
reportError(tok, Severity::warning, "uninitMemberVar", "Member variable '" + classname + "::" + varname + "' is not initialized in the constructor.", inconclusive); reportError(tok, Severity::warning, "uninitMemberVar", "Member variable '" + classname + "::" + varname + "' is not initialized in the constructor.", 0U, inconclusive);
} }
void CheckClass::operatorEqVarError(const Token *tok, const std::string &classname, const std::string &varname, bool inconclusive) void CheckClass::operatorEqVarError(const Token *tok, const std::string &classname, const std::string &varname, bool inconclusive)
{ {
reportError(tok, Severity::warning, "operatorEqVarError", "Member variable '" + classname + "::" + varname + "' is not assigned a value in '" + classname + "::operator='.", inconclusive); reportError(tok, Severity::warning, "operatorEqVarError", "Member variable '" + classname + "::" + varname + "' is not assigned a value in '" + classname + "::operator='.", 0U, inconclusive);
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@ -1129,7 +1129,7 @@ void CheckClass::mallocOnClassWarning(const Token* tok, const std::string &memfu
reportError(toks, Severity::warning, "mallocOnClassWarning", reportError(toks, Severity::warning, "mallocOnClassWarning",
"Memory for class instance allocated with " + memfunc + "(), but class provides constructors.\n" "Memory for class instance allocated with " + memfunc + "(), but class provides constructors.\n"
"Memory for class instance allocated with " + memfunc + "(), but class provides constructors. This is unsafe, " "Memory for class instance allocated with " + memfunc + "(), but class provides constructors. This is unsafe, "
"since no constructor is called and class members remain uninitialized. Consider using 'new' instead."); "since no constructor is called and class members remain uninitialized. Consider using 'new' instead.", 0U, false);
} }
void CheckClass::mallocOnClassError(const Token* tok, const std::string &memfunc, const Token* classTok, const std::string &classname) void CheckClass::mallocOnClassError(const Token* tok, const std::string &memfunc, const Token* classTok, const std::string &classname)
@ -1140,7 +1140,7 @@ void CheckClass::mallocOnClassError(const Token* tok, const std::string &memfunc
reportError(toks, Severity::error, "mallocOnClassError", reportError(toks, Severity::error, "mallocOnClassError",
"Memory for class instance allocated with " + memfunc + "(), but class contains a " + classname + ".\n" "Memory for class instance allocated with " + memfunc + "(), but class contains a " + classname + ".\n"
"Memory for class instance allocated with " + memfunc + "(), but class a " + classname + ". This is unsafe, " "Memory for class instance allocated with " + memfunc + "(), but class a " + classname + ". This is unsafe, "
"since no constructor is called and class members remain uninitialized. Consider using 'new' instead."); "since no constructor is called and class members remain uninitialized. Consider using 'new' instead.", 0U, false);
} }
void CheckClass::memsetError(const Token *tok, const std::string &memfunc, const std::string &classname, const std::string &type) void CheckClass::memsetError(const Token *tok, const std::string &memfunc, const std::string &classname, const std::string &type)
@ -1604,7 +1604,7 @@ void CheckClass::virtualDestructor()
void CheckClass::virtualDestructorError(const Token *tok, const std::string &Base, const std::string &Derived, bool inconclusive) void CheckClass::virtualDestructorError(const Token *tok, const std::string &Base, const std::string &Derived, bool inconclusive)
{ {
if (inconclusive) if (inconclusive)
reportError(tok, Severity::warning, "virtualDestructor", "Class '" + Base + "' which has virtual members does not have a virtual destructor.", true); reportError(tok, Severity::warning, "virtualDestructor", "Class '" + Base + "' which has virtual members does not have a virtual destructor.", 0U, true);
else else
reportError(tok, Severity::error, "virtualDestructor", "Class '" + Base + "' which is inherited by class '" + Derived + "' does not have a virtual destructor.\n" reportError(tok, Severity::error, "virtualDestructor", "Class '" + Base + "' which is inherited by class '" + Derived + "' does not have a virtual destructor.\n"
"Class '" + Base + "' which is inherited by class '" + Derived + "' does not have a virtual destructor. " "Class '" + Base + "' which is inherited by class '" + Derived + "' does not have a virtual destructor. "
@ -1973,7 +1973,7 @@ void CheckClass::checkConstError2(const Token *tok1, const Token *tok2, const st
"function. Making this function 'const' should not cause compiler errors. " "function. Making this function 'const' should not cause compiler errors. "
"Even though the function can be made const function technically it may not make " "Even though the function can be made const function technically it may not make "
"sense conceptually. Think about your design and the task of the function first - is " "sense conceptually. Think about your design and the task of the function first - is "
"it a function that must not change object internal state?", true); "it a function that must not change object internal state?", 0U, true);
else else
reportError(toks, Severity::performance, "functionStatic", reportError(toks, Severity::performance, "functionStatic",
"Technically the member function '" + classname + "::" + funcname + "' can be static.\n" "Technically the member function '" + classname + "::" + funcname + "' can be static.\n"
@ -1981,7 +1981,7 @@ void CheckClass::checkConstError2(const Token *tok1, const Token *tok2, const st
"function. Making a function static can bring a performance benefit since no 'this' instance is " "function. Making a function static can bring a performance benefit since no 'this' instance is "
"passed to the function. This change should not cause compiler errors but it does not " "passed to the function. This change should not cause compiler errors but it does not "
"necessarily make sense conceptually. Think about your design and the task of the function first - " "necessarily make sense conceptually. Think about your design and the task of the function first - "
"is it a function that must not access members of class instances?", true); "is it a function that must not access members of class instances?", 0U, true);
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@ -2066,7 +2066,7 @@ void CheckClass::initializerListError(const Token *tok1, const Token *tok2, cons
"Members are initialized in the order they are declared, not in the " "Members are initialized in the order they are declared, not in the "
"order they are in the initializer list. Keeping the initializer list " "order they are in the initializer list. Keeping the initializer list "
"in the same order that the members were declared prevents order dependent " "in the same order that the members were declared prevents order dependent "
"initialization errors.", true); "initialization errors.", 0U, true);
} }
@ -2215,7 +2215,7 @@ void CheckClass::callsPureVirtualFunctionError(
{ {
const char * scopeFunctionTypeName = getFunctionTypeName(scopeFunction.type); const char * scopeFunctionTypeName = getFunctionTypeName(scopeFunction.type);
reportError(tokStack, Severity::warning, "pureVirtualCall", "Call of pure virtual function '" + purefuncname + "' in " + scopeFunctionTypeName + ".\n" reportError(tokStack, Severity::warning, "pureVirtualCall", "Call of pure virtual function '" + purefuncname + "' in " + scopeFunctionTypeName + ".\n"
"Call of pure virtual function '" + purefuncname + "' in " + scopeFunctionTypeName + ". The call will fail during runtime."); "Call of pure virtual function '" + purefuncname + "' in " + scopeFunctionTypeName + ". The call will fail during runtime.", 0U, false);
} }
@ -2269,5 +2269,5 @@ void CheckClass::duplInheritedMembersError(const Token *tok1, const Token* tok2,
const std::string message = "The " + std::string(derivedIsStruct ? "struct" : "class") + " '" + derivedname + const std::string message = "The " + std::string(derivedIsStruct ? "struct" : "class") + " '" + derivedname +
"' defines member variable with name '" + variablename + "' also defined in its parent " + "' defines member variable with name '" + variablename + "' also defined in its parent " +
std::string(baseIsStruct ? "struct" : "class") + " '" + basename + "'."; std::string(baseIsStruct ? "struct" : "class") + " '" + basename + "'.";
reportError(toks, Severity::warning, "duplInheritedMember", message); reportError(toks, Severity::warning, "duplInheritedMember", message, 0U, false);
} }

View File

@ -122,7 +122,7 @@ private:
reportError(locationList, Severity::style, "unhandledExceptionSpecification", reportError(locationList, Severity::style, "unhandledExceptionSpecification",
"Unhandled exception specification when calling function " + str1 + "().\n" "Unhandled exception specification when calling function " + str1 + "().\n"
"Unhandled exception specification when calling function " + str1 + "(). " "Unhandled exception specification when calling function " + str1 + "(). "
"Either use a try/catch around the function call, or add a exception specification for " + funcname + "() also.", true); "Either use a try/catch around the function call, or add a exception specification for " + funcname + "() also.", 0U, true);
} }
/** Generate all possible errors (for --errorlist) */ /** Generate all possible errors (for --errorlist) */

View File

@ -1971,10 +1971,10 @@ void CheckIO::invalidScanfFormatWidthError(const Token* tok, unsigned int numFor
return; return;
errmsg << "Width " << width << " given in format string (no. " << numFormat << ") is smaller than destination buffer" errmsg << "Width " << width << " given in format string (no. " << numFormat << ") is smaller than destination buffer"
<< " '" << varname << "[" << arrlen << "]'."; << " '" << varname << "[" << arrlen << "]'.";
reportError(tok, Severity::warning, "invalidScanfFormatWidth_smaller", errmsg.str(), true); reportError(tok, Severity::warning, "invalidScanfFormatWidth_smaller", errmsg.str(), 0U, true);
} else { } else {
errmsg << "Width " << width << " given in format string (no. " << numFormat << ") is larger than destination buffer '" errmsg << "Width " << width << " given in format string (no. " << numFormat << ") is larger than destination buffer '"
<< varname << "[" << arrlen << "]', use %" << (arrlen - 1) << "s to prevent overflowing it."; << varname << "[" << arrlen << "]', use %" << (arrlen - 1) << "s to prevent overflowing it.";
reportError(tok, Severity::error, "invalidScanfFormatWidth", errmsg.str(), false); reportError(tok, Severity::error, "invalidScanfFormatWidth", errmsg.str(), 0U, false);
} }
} }

View File

@ -340,20 +340,20 @@ void CheckMemoryLeak::memoryLeak(const Token *tok, const std::string &varname, A
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
void CheckMemoryLeak::reportErr(const Token *tok, Severity::SeverityType severity, const std::string &id, const std::string &msg, unsigned int cwe) const
void CheckMemoryLeak::reportErr(const Token *tok, Severity::SeverityType severity, const std::string &id, const std::string &msg) const
{ {
std::list<const Token *> callstack; std::list<const Token *> callstack;
if (tok) if (tok)
callstack.push_back(tok); callstack.push_back(tok);
reportErr(callstack, severity, id, msg); reportErr(callstack, severity, id, msg, cwe);
} }
void CheckMemoryLeak::reportErr(const std::list<const Token *> &callstack, Severity::SeverityType severity, const std::string &id, const std::string &msg) const void CheckMemoryLeak::reportErr(const std::list<const Token *> &callstack, Severity::SeverityType severity, const std::string &id, const std::string &msg, unsigned int cwe) const
{ {
const ErrorLogger::ErrorMessage errmsg(callstack, tokenizer?&tokenizer->list:0, severity, id, msg, false); ErrorLogger::ErrorMessage errmsg(callstack, tokenizer?&tokenizer->list:0, severity, id, msg, false);
errmsg._cwe = cwe;
if (errorLogger) if (errorLogger)
errorLogger->reportErr(errmsg); errorLogger->reportErr(errmsg);
@ -363,12 +363,12 @@ void CheckMemoryLeak::reportErr(const std::list<const Token *> &callstack, Sever
void CheckMemoryLeak::memleakError(const Token *tok, const std::string &varname) const void CheckMemoryLeak::memleakError(const Token *tok, const std::string &varname) const
{ {
reportErr(tok, Severity::error, "memleak", "Memory leak: " + varname); reportErr(tok, Severity::error, "memleak", "Memory leak: " + varname, 0U);
} }
void CheckMemoryLeak::memleakUponReallocFailureError(const Token *tok, const std::string &varname) const void CheckMemoryLeak::memleakUponReallocFailureError(const Token *tok, const std::string &varname) const
{ {
reportErr(tok, Severity::error, "memleakOnRealloc", "Common realloc mistake: \'" + varname + "\' nulled but not freed upon failure"); reportErr(tok, Severity::error, "memleakOnRealloc", "Common realloc mistake: \'" + varname + "\' nulled but not freed upon failure", 0U);
} }
void CheckMemoryLeak::resourceLeakError(const Token *tok, const std::string &varname) const void CheckMemoryLeak::resourceLeakError(const Token *tok, const std::string &varname) const
@ -376,27 +376,27 @@ void CheckMemoryLeak::resourceLeakError(const Token *tok, const std::string &var
std::string errmsg("Resource leak"); std::string errmsg("Resource leak");
if (!varname.empty()) if (!varname.empty())
errmsg += ": " + varname; errmsg += ": " + varname;
reportErr(tok, Severity::error, "resourceLeak", errmsg); reportErr(tok, Severity::error, "resourceLeak", errmsg, 775U);
} }
void CheckMemoryLeak::deallocDeallocError(const Token *tok, const std::string &varname) const void CheckMemoryLeak::deallocDeallocError(const Token *tok, const std::string &varname) const
{ {
reportErr(tok, Severity::error, "deallocDealloc", "Deallocating a deallocated pointer: " + varname); reportErr(tok, Severity::error, "deallocDealloc", "Deallocating a deallocated pointer: " + varname, 0U);
} }
void CheckMemoryLeak::deallocuseError(const Token *tok, const std::string &varname) const void CheckMemoryLeak::deallocuseError(const Token *tok, const std::string &varname) const
{ {
reportErr(tok, Severity::error, "deallocuse", "Dereferencing '" + varname + "' after it is deallocated / released"); reportErr(tok, Severity::error, "deallocuse", "Dereferencing '" + varname + "' after it is deallocated / released", 0U);
} }
void CheckMemoryLeak::mismatchSizeError(const Token *tok, const std::string &sz) const void CheckMemoryLeak::mismatchSizeError(const Token *tok, const std::string &sz) const
{ {
reportErr(tok, Severity::error, "mismatchSize", "The allocated size " + sz + " is not a multiple of the underlying type's size."); reportErr(tok, Severity::error, "mismatchSize", "The allocated size " + sz + " is not a multiple of the underlying type's size.", 0U);
} }
void CheckMemoryLeak::mismatchAllocDealloc(const std::list<const Token *> &callstack, const std::string &varname) const void CheckMemoryLeak::mismatchAllocDealloc(const std::list<const Token *> &callstack, const std::string &varname) const
{ {
reportErr(callstack, Severity::error, "mismatchAllocDealloc", "Mismatching allocation and deallocation: " + varname); reportErr(callstack, Severity::error, "mismatchAllocDealloc", "Mismatching allocation and deallocation: " + varname, 0U);
} }
CheckMemoryLeak::AllocType CheckMemoryLeak::functionReturnType(const Function* func, std::list<const Function*> *callstack) const CheckMemoryLeak::AllocType CheckMemoryLeak::functionReturnType(const Function* func, std::list<const Function*> *callstack) const
@ -2817,5 +2817,6 @@ void CheckMemoryLeakNoVar::unsafeArgAllocError(const Token *tok, const std::stri
const std::string factoryFunc = ptrType == "shared_ptr" ? "make_shared" : "make_unique"; const std::string factoryFunc = ptrType == "shared_ptr" ? "make_shared" : "make_unique";
reportError(tok, Severity::warning, "leakUnsafeArgAlloc", reportError(tok, Severity::warning, "leakUnsafeArgAlloc",
"Unsafe allocation. If " + funcName + "() throws, memory could be leaked. Use " + factoryFunc + "<" + objType + ">() instead.", "Unsafe allocation. If " + funcName + "() throws, memory could be leaked. Use " + factoryFunc + "<" + objType + ">() instead.",
0U,
true); // Inconclusive because funcName may never throw true); // Inconclusive because funcName may never throw
} }

View File

@ -73,8 +73,9 @@ private:
* @param severity the severity of the bug * @param severity the severity of the bug
* @param id type of message * @param id type of message
* @param msg text * @param msg text
* @param cwe cwe number
*/ */
void reportErr(const Token *location, Severity::SeverityType severity, const std::string &id, const std::string &msg) const; void reportErr(const Token *location, Severity::SeverityType severity, const std::string &id, const std::string &msg, unsigned int cwe) const;
/** /**
* Report error. Similar with the function Check::reportError * Report error. Similar with the function Check::reportError
@ -82,8 +83,9 @@ private:
* @param severity the severity of the bug * @param severity the severity of the bug
* @param id type of message * @param id type of message
* @param msg text * @param msg text
* @param cwe cwe number
*/ */
void reportErr(const std::list<const Token *> &callstack, Severity::SeverityType severity, const std::string &id, const std::string &msg) const; void reportErr(const std::list<const Token *> &callstack, Severity::SeverityType severity, const std::string &id, const std::string &msg, unsigned int cwe) const;
public: public:
CheckMemoryLeak(const Tokenizer *t, ErrorLogger *e, const Settings *s) CheckMemoryLeak(const Tokenizer *t, ErrorLogger *e, const Settings *s)

View File

@ -468,9 +468,9 @@ void CheckNullPointer::nullPointerError(const Token *tok, const std::string &var
{ {
if (defaultArg) { if (defaultArg) {
if (_settings->isEnabled("warning")) if (_settings->isEnabled("warning"))
reportError(tok, Severity::warning, "nullPointer", "Possible null pointer dereference if the default parameter value is used: " + varname, inconclusive); reportError(tok, Severity::warning, "nullPointer", "Possible null pointer dereference if the default parameter value is used: " + varname, 0U, inconclusive);
} else } else
reportError(tok, Severity::error, "nullPointer", "Possible null pointer dereference: " + varname, inconclusive); reportError(tok, Severity::error, "nullPointer", "Possible null pointer dereference: " + varname, 0U, inconclusive);
} }
void CheckNullPointer::nullPointerError(const Token *tok, const std::string &varname, const Token* nullCheck, bool inconclusive) void CheckNullPointer::nullPointerError(const Token *tok, const std::string &varname, const Token* nullCheck, bool inconclusive)
@ -479,5 +479,5 @@ void CheckNullPointer::nullPointerError(const Token *tok, const std::string &var
callstack.push_back(tok); callstack.push_back(tok);
callstack.push_back(nullCheck); callstack.push_back(nullCheck);
const std::string errmsg("Possible null pointer dereference: " + varname + " - otherwise it is redundant to check it against null."); const std::string errmsg("Possible null pointer dereference: " + varname + " - otherwise it is redundant to check it against null.");
reportError(callstack, Severity::warning, "nullPointer", errmsg, inconclusive); reportError(callstack, Severity::warning, "nullPointer", errmsg, 0U, inconclusive);
} }

View File

@ -353,7 +353,7 @@ void CheckOther::checkSuspiciousSemicolon()
void CheckOther::SuspiciousSemicolonError(const Token* tok) void CheckOther::SuspiciousSemicolonError(const Token* tok)
{ {
reportError(tok, Severity::warning, "suspiciousSemicolon", reportError(tok, Severity::warning, "suspiciousSemicolon",
"Suspicious use of ; at the end of '" + (tok ? tok->str() : std::string()) + "' statement.", true); "Suspicious use of ; at the end of '" + (tok ? tok->str() : std::string()) + "' statement.", 0U, true);
} }
@ -504,7 +504,7 @@ void CheckOther::invalidPointerCastError(const Token* tok, const std::string& fr
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.");
else else
reportError(tok, Severity::portability, "invalidPointerCast", "Casting from " + from + "* to char* is not portable due to different binary data representations on different platforms.", true); reportError(tok, Severity::portability, "invalidPointerCast", "Casting from " + from + "* to char* is not portable due to different binary data representations on different platforms.", 0U, 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.");
} }
@ -758,7 +758,7 @@ void CheckOther::redundantAssignmentError(const Token *tok1, const Token* tok2,
if (inconclusive) if (inconclusive)
reportError(callstack, Severity::performance, "redundantAssignment", reportError(callstack, Severity::performance, "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.", 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.", 0U, true);
else else
reportError(callstack, Severity::performance, "redundantAssignment", reportError(callstack, Severity::performance, "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.");
@ -999,7 +999,7 @@ void CheckOther::suspiciousCaseInSwitchError(const Token* tok, const std::string
{ {
reportError(tok, Severity::warning, "suspiciousCase", reportError(tok, Severity::warning, "suspiciousCase",
"Found suspicious case label in switch(). Operator '" + operatorString + "' probably doesn't work as intended.\n" "Found suspicious case label in switch(). Operator '" + operatorString + "' probably doesn't work as intended.\n"
"Using an operator like '" + operatorString + "' in a case label is suspicious. Did you intend to use a bitwise operator, multiple case labels or if/else instead?", true); "Using an operator like '" + operatorString + "' in a case label is suspicious. Did you intend to use a bitwise operator, multiple case labels or if/else instead?", 0U, true);
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@ -1061,7 +1061,7 @@ void CheckOther::checkSuspiciousEqualityComparison()
void CheckOther::suspiciousEqualityComparisonError(const Token* tok) void CheckOther::suspiciousEqualityComparisonError(const Token* tok)
{ {
reportError(tok, Severity::warning, "suspiciousEqualityComparison", reportError(tok, Severity::warning, "suspiciousEqualityComparison",
"Found suspicious equality comparison. Did you intend to assign a value instead?", true); "Found suspicious equality comparison. Did you intend to assign a value instead?", 0U, true);
} }
@ -1235,13 +1235,13 @@ void CheckOther::duplicateBreakError(const Token *tok, bool inconclusive)
reportError(tok, Severity::style, "duplicateBreak", reportError(tok, Severity::style, "duplicateBreak",
"Consecutive return, break, continue, goto or throw statements are unnecessary.\n" "Consecutive return, break, continue, goto or throw statements are unnecessary.\n"
"Consecutive return, break, continue, goto or throw statements are unnecessary. " "Consecutive return, break, continue, goto or throw statements are unnecessary. "
"The second statement can never be executed, and so should be removed.", inconclusive); "The second statement can never be executed, and so should be removed.", 0U, inconclusive);
} }
void CheckOther::unreachableCodeError(const Token *tok, bool inconclusive) void CheckOther::unreachableCodeError(const Token *tok, bool inconclusive)
{ {
reportError(tok, Severity::style, "unreachableCode", reportError(tok, Severity::style, "unreachableCode",
"Statements following return, break, continue, goto or throw will never be executed.", inconclusive); "Statements following return, break, continue, goto or throw will never be executed.", 0U, inconclusive);
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@ -1818,7 +1818,7 @@ void CheckOther::checkZeroDivision()
void CheckOther::zerodivError(const Token *tok, bool inconclusive) void CheckOther::zerodivError(const Token *tok, bool inconclusive)
{ {
reportError(tok, Severity::error, "zerodiv", "Division by zero.", inconclusive); reportError(tok, Severity::error, "zerodiv", "Division by zero.", 0U, inconclusive);
} }
void CheckOther::zerodivcondError(const Token *tokcond, const Token *tokdiv, bool inconclusive) void CheckOther::zerodivcondError(const Token *tokcond, const Token *tokdiv, bool inconclusive)
@ -1844,7 +1844,7 @@ void CheckOther::zerodivcondError(const Token *tokcond, const Token *tokdiv, boo
condition = tokcond->str() + "!=0"; condition = tokcond->str() + "!=0";
} }
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", "Either the condition '"+condition+"' is useless or there is division by zero at line " + linenr + ".", inconclusive); reportError(callstack, Severity::warning, "zerodivcond", "Either the condition '"+condition+"' is useless or there is division by zero at line " + linenr + ".", 0U, inconclusive);
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@ -2061,7 +2061,7 @@ void CheckOther::duplicateBranchError(const Token *tok1, const Token *tok2)
reportError(toks, Severity::style, "duplicateBranch", "Found duplicate branches for 'if' and 'else'.\n" reportError(toks, Severity::style, "duplicateBranch", "Found duplicate branches for 'if' and 'else'.\n"
"Finding the same code in an 'if' and related 'else' branch is suspicious and " "Finding the same code in an 'if' and related 'else' branch is suspicious and "
"might indicate a cut and paste or logic error. Please examine this code " "might indicate a cut and paste or logic error. Please examine this code "
"carefully to determine if it is correct.", true); "carefully to determine if it is correct.", 0U, true);
} }
@ -2139,7 +2139,7 @@ void CheckOther::checkInvalidFree()
void CheckOther::invalidFreeError(const Token *tok, bool inconclusive) void CheckOther::invalidFreeError(const Token *tok, bool inconclusive)
{ {
reportError(tok, Severity::error, "invalidFree", "Invalid memory address freed.", inconclusive); reportError(tok, Severity::error, "invalidFree", "Invalid memory address freed.", 0U, inconclusive);
} }
@ -2394,7 +2394,7 @@ void CheckOther::unsignedLessThanZeroError(const Token *tok, const std::string &
"Checking if unsigned variable '" + varname + "' is less than zero. An unsigned " "Checking if unsigned variable '" + varname + "' is less than zero. An unsigned "
"variable will never be negative so it is either pointless or an error to check if it is. " "variable will never be negative so it is either pointless or an error to check if it is. "
"It's not known if the used constant is a template parameter or not and therefore " "It's not known if the used constant is a template parameter or not and therefore "
"this message might be a false warning.", true); "this message might be a false warning.", 0U, true);
} else { } else {
reportError(tok, Severity::style, "unsignedLessThanZero", reportError(tok, Severity::style, "unsignedLessThanZero",
"Checking if unsigned variable '" + varname + "' is less than zero.\n" "Checking if unsigned variable '" + varname + "' is less than zero.\n"
@ -2406,7 +2406,7 @@ void CheckOther::unsignedLessThanZeroError(const Token *tok, const std::string &
void CheckOther::pointerLessThanZeroError(const Token *tok, bool inconclusive) void CheckOther::pointerLessThanZeroError(const Token *tok, bool inconclusive)
{ {
reportError(tok, Severity::style, "pointerLessThanZero", reportError(tok, Severity::style, "pointerLessThanZero",
"A pointer can not be negative so it is either pointless or an error to check if it is.", inconclusive); "A pointer can not be negative so it is either pointless or an error to check if it is.", 0U, inconclusive);
} }
void CheckOther::unsignedPositiveError(const Token *tok, const std::string &varname, bool inconclusive) void CheckOther::unsignedPositiveError(const Token *tok, const std::string &varname, bool inconclusive)
@ -2416,7 +2416,7 @@ void CheckOther::unsignedPositiveError(const Token *tok, const std::string &varn
"Unsigned variable '" + varname + "' can't be negative so it is unnecessary to test it.\n" "Unsigned variable '" + varname + "' can't be negative so it is unnecessary to test it.\n"
"The unsigned variable '" + varname + "' can't be negative so it is unnecessary to test it. " "The unsigned variable '" + varname + "' can't be negative so it is unnecessary to test it. "
"It's not known if the used constant is a " "It's not known if the used constant is a "
"template parameter or not and therefore this message might be a false warning", true); "template parameter or not and therefore this message might be a false warning", 0U, true);
} else { } else {
reportError(tok, Severity::style, "unsignedPositive", reportError(tok, Severity::style, "unsignedPositive",
"Unsigned variable '" + varname + "' can't be negative so it is unnecessary to test it."); "Unsigned variable '" + varname + "' can't be negative so it is unnecessary to test it.");
@ -2426,7 +2426,7 @@ void CheckOther::unsignedPositiveError(const Token *tok, const std::string &varn
void CheckOther::pointerPositiveError(const Token *tok, bool inconclusive) void CheckOther::pointerPositiveError(const Token *tok, bool inconclusive)
{ {
reportError(tok, Severity::style, "pointerPositive", reportError(tok, Severity::style, "pointerPositive",
"A pointer can not be negative so it is either pointless or an error to check if it is not.", inconclusive); "A pointer can not be negative so it is either pointless or an error to check if it is not.", 0U, inconclusive);
} }
/* check if a constructor in given class scope takes a reference */ /* check if a constructor in given class scope takes a reference */
@ -2493,6 +2493,7 @@ void CheckOther::redundantCopyError(const Token *tok,const std::string& varname)
"Use const reference for '" + varname + "' to avoid unnecessary data copying.\n" "Use const reference for '" + varname + "' to avoid unnecessary data copying.\n"
"The const variable '"+varname+"' is assigned a copy of the data. You can avoid " "The const variable '"+varname+"' is assigned a copy of the data. You can avoid "
"the unnecessary data copying by converting '" + varname + "' to const reference.", "the unnecessary data copying by converting '" + varname + "' to const reference.",
0U,
true); // since #5618 that check became inconlusive true); // since #5618 that check became inconlusive
} }
@ -2593,11 +2594,11 @@ void CheckOther::incompleteArrayFillError(const Token* tok, const std::string& b
if (boolean) if (boolean)
reportError(tok, Severity::portability, "incompleteArrayFill", reportError(tok, Severity::portability, "incompleteArrayFill",
"Array '" + buffer + "' might be filled incompletely. Did you forget to multiply the size given to '" + function + "()' with 'sizeof(*" + buffer + ")'?\n" "Array '" + buffer + "' might be filled incompletely. Did you forget to multiply the size given to '" + function + "()' with 'sizeof(*" + buffer + ")'?\n"
"The array '" + buffer + "' is filled incompletely. The function '" + function + "()' needs the size given in bytes, but the type 'bool' is larger than 1 on some platforms. Did you forget to multiply the size with 'sizeof(*" + buffer + ")'?", true); "The array '" + buffer + "' is filled incompletely. The function '" + function + "()' needs the size given in bytes, but the type 'bool' is larger than 1 on some platforms. Did you forget to multiply the size with 'sizeof(*" + buffer + ")'?", 0U, true);
else else
reportError(tok, Severity::warning, "incompleteArrayFill", reportError(tok, Severity::warning, "incompleteArrayFill",
"Array '" + buffer + "' is filled incompletely. Did you forget to multiply the size given to '" + function + "()' with 'sizeof(*" + buffer + ")'?\n" "Array '" + buffer + "' is filled incompletely. Did you forget to multiply the size given to '" + function + "()' with 'sizeof(*" + buffer + ")'?\n"
"The array '" + buffer + "' is filled incompletely. The function '" + function + "()' needs the size given in bytes, but an element of the given array is larger than one byte. Did you forget to multiply the size with 'sizeof(*" + buffer + ")'?", true); "The array '" + buffer + "' is filled incompletely. The function '" + function + "()' needs the size given in bytes, but an element of the given array is larger than one byte. Did you forget to multiply the size with 'sizeof(*" + buffer + ")'?", 0U, true);
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@ -2717,7 +2718,7 @@ void CheckOther::checkIgnoredReturnValue()
void CheckOther::ignoredReturnValueError(const Token* tok, const std::string& function) void CheckOther::ignoredReturnValueError(const Token* tok, const std::string& function)
{ {
reportError(tok, Severity::warning, "ignoredReturnValue", reportError(tok, Severity::warning, "ignoredReturnValue",
"Return value of function " + function + "() is not used.", false); "Return value of function " + function + "() is not used.", 0U, false);
} }
void CheckOther::checkRedundantPointerOp() void CheckOther::checkRedundantPointerOp()
@ -2754,7 +2755,7 @@ void CheckOther::checkRedundantPointerOp()
void CheckOther::redundantPointerOpError(const Token* tok, const std::string &varname, bool inconclusive) void CheckOther::redundantPointerOpError(const Token* tok, const std::string &varname, bool inconclusive)
{ {
reportError(tok, Severity::style, "redundantPointerOp", reportError(tok, Severity::style, "redundantPointerOp",
"Redundant pointer operation on " + varname + " - it's already a pointer.", inconclusive); "Redundant pointer operation on " + varname + " - it's already a pointer.", 0U, inconclusive);
} }
void CheckOther::checkLibraryMatchFunctions() void CheckOther::checkLibraryMatchFunctions()

View File

@ -260,7 +260,7 @@ void CheckSizeof::sizeofCalculation()
void CheckSizeof::sizeofCalculationError(const Token *tok, bool inconclusive) void CheckSizeof::sizeofCalculationError(const Token *tok, bool inconclusive)
{ {
reportError(tok, Severity::warning, reportError(tok, Severity::warning,
"sizeofCalculation", "Found calculation inside sizeof().", inconclusive); "sizeofCalculation", "Found calculation inside sizeof().", 0U, inconclusive);
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -288,7 +288,7 @@ void CheckSizeof::suspiciousSizeofCalculation()
void CheckSizeof::multiplySizeofError(const Token *tok) void CheckSizeof::multiplySizeofError(const Token *tok)
{ {
reportError(tok, Severity::warning, reportError(tok, Severity::warning,
"multiplySizeof", "Multiplying sizeof() with sizeof() indicates a logic error.", true); "multiplySizeof", "Multiplying sizeof() with sizeof() indicates a logic error.", 0U, true);
} }
void CheckSizeof::divideSizeofError(const Token *tok) void CheckSizeof::divideSizeofError(const Token *tok)
@ -296,7 +296,7 @@ void CheckSizeof::divideSizeofError(const Token *tok)
reportError(tok, Severity::warning, reportError(tok, Severity::warning,
"divideSizeof", "Division of result of sizeof() on pointer type.\n" "divideSizeof", "Division of result of sizeof() on pointer type.\n"
"Division of result of sizeof() on pointer type. sizeof() returns the size of the pointer, " "Division of result of sizeof() on pointer type. sizeof() returns the size of the pointer, "
"not the size of the memory area it points to.", true); "not the size of the memory area it points to.", 0U, true);
} }
void CheckSizeof::sizeofVoid() void CheckSizeof::sizeofVoid()

View File

@ -1612,5 +1612,5 @@ void CheckStl::readingEmptyStlContainer()
void CheckStl::readingEmptyStlContainerError(const Token *tok) void CheckStl::readingEmptyStlContainerError(const Token *tok)
{ {
reportError(tok, Severity::style, "reademptycontainer", "Reading from empty STL container", true); reportError(tok, Severity::style, "reademptycontainer", "Reading from empty STL container", 0U, true);
} }

View File

@ -156,7 +156,7 @@ void CheckType::tooBigBitwiseShiftError(const Token *tok, int lhsbits, const Val
errmsg << "Shifting " << lhsbits << "-bit value by " << rhsbits.intvalue << " bits is undefined behaviour"; errmsg << "Shifting " << lhsbits << "-bit value by " << rhsbits.intvalue << " bits is undefined behaviour";
if (rhsbits.condition) if (rhsbits.condition)
errmsg << ". See condition at line " << rhsbits.condition->linenr() << "."; errmsg << ". See condition at line " << rhsbits.condition->linenr() << ".";
reportError(callstack, rhsbits.condition ? Severity::warning : Severity::error, "shiftTooManyBits", errmsg.str(), rhsbits.inconclusive); reportError(callstack, rhsbits.condition ? Severity::warning : Severity::error, "shiftTooManyBits", errmsg.str(), 0U, rhsbits.inconclusive);
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@ -211,6 +211,7 @@ void CheckType::integerOverflowError(const Token *tok, const ValueFlow::Value &v
value.condition ? Severity::warning : Severity::error, value.condition ? Severity::warning : Severity::error,
"integerOverflow", "integerOverflow",
"Signed integer overflow for expression '"+expr+"'"+cond, "Signed integer overflow for expression '"+expr+"'"+cond,
0U,
value.inconclusive); value.inconclusive);
} }

View File

@ -45,7 +45,7 @@ InternalError::InternalError(const Token *tok, const std::string &errorMsg, Type
} }
ErrorLogger::ErrorMessage::ErrorMessage() ErrorLogger::ErrorMessage::ErrorMessage()
: _severity(Severity::none), _inconclusive(false) : _severity(Severity::none), _cwe(0U), _inconclusive(false)
{ {
} }
@ -53,6 +53,7 @@ ErrorLogger::ErrorMessage::ErrorMessage(const std::list<FileLocation> &callStack
_callStack(callStack), // locations for this error message _callStack(callStack), // locations for this error message
_id(id), // set the message id _id(id), // set the message id
_severity(severity), // severity for this error message _severity(severity), // severity for this error message
_cwe(0U),
_inconclusive(inconclusive) _inconclusive(inconclusive)
{ {
// set the summary and verbose messages // set the summary and verbose messages
@ -60,7 +61,7 @@ ErrorLogger::ErrorMessage::ErrorMessage(const std::list<FileLocation> &callStack
} }
ErrorLogger::ErrorMessage::ErrorMessage(const std::list<const Token*>& callstack, const TokenList* list, Severity::SeverityType severity, const std::string& id, const std::string& msg, bool inconclusive) ErrorLogger::ErrorMessage::ErrorMessage(const std::list<const Token*>& callstack, const TokenList* list, Severity::SeverityType severity, const std::string& id, const std::string& msg, bool inconclusive)
: _id(id), _severity(severity), _inconclusive(inconclusive) : _id(id), _severity(severity), _cwe(0U), _inconclusive(inconclusive)
{ {
// Format callstack // Format callstack
for (std::list<const Token *>::const_iterator it = callstack.begin(); it != callstack.end(); ++it) { for (std::list<const Token *>::const_iterator it = callstack.begin(); it != callstack.end(); ++it) {
@ -105,6 +106,7 @@ std::string ErrorLogger::ErrorMessage::serialize() const
std::ostringstream oss; std::ostringstream oss;
oss << _id.length() << " " << _id; oss << _id.length() << " " << _id;
oss << Severity::toString(_severity).length() << " " << Severity::toString(_severity); oss << Severity::toString(_severity).length() << " " << Severity::toString(_severity);
oss << MathLib::toString(_cwe).length() << " " << MathLib::toString(_cwe);
if (_inconclusive) { if (_inconclusive) {
const std::string inconclusive("inconclusive"); const std::string inconclusive("inconclusive");
oss << inconclusive.length() << " " << inconclusive; oss << inconclusive.length() << " " << inconclusive;
@ -150,17 +152,18 @@ bool ErrorLogger::ErrorMessage::deserialize(const std::string &data)
} }
results.push_back(temp); results.push_back(temp);
if (results.size() == 4) if (results.size() == 5)
break; break;
} }
if (results.size() != 4) if (results.size() != 5)
throw InternalError(0, "Internal Error: Deserialization of error message failed"); throw InternalError(0, "Internal Error: Deserialization of error message failed");
_id = results[0]; _id = results[0];
_severity = Severity::fromString(results[1]); _severity = Severity::fromString(results[1]);
_shortMessage = results[2]; _cwe = MathLib::toULongNumber(results[2]);
_verboseMessage = results[3]; _shortMessage = results[3];
_verboseMessage = results[4];
unsigned int stackSize = 0; unsigned int stackSize = 0;
if (!(iss >> stackSize)) if (!(iss >> stackSize))
@ -271,6 +274,8 @@ std::string ErrorLogger::ErrorMessage::toXML(bool verbose, int version) const
printer.PushAttribute("severity", Severity::toString(_severity).c_str()); printer.PushAttribute("severity", Severity::toString(_severity).c_str());
printer.PushAttribute("msg", _shortMessage.c_str()); printer.PushAttribute("msg", _shortMessage.c_str());
printer.PushAttribute("verbose", fixInvalidChars(_verboseMessage).c_str()); printer.PushAttribute("verbose", fixInvalidChars(_verboseMessage).c_str());
if (_cwe)
printer.PushAttribute("cwe", _cwe);
if (_inconclusive) if (_inconclusive)
printer.PushAttribute("inconclusive", "true"); printer.PushAttribute("inconclusive", "true");

View File

@ -230,6 +230,7 @@ public:
std::string file0; std::string file0;
Severity::SeverityType _severity; Severity::SeverityType _severity;
unsigned int _cwe;
bool _inconclusive; bool _inconclusive;
/** set short and verbose messages */ /** set short and verbose messages */

View File

@ -249,6 +249,7 @@ private:
ErrorMessage msg(locs, Severity::error, "Programming error", "errorId", true); ErrorMessage msg(locs, Severity::error, "Programming error", "errorId", true);
ASSERT_EQUALS("7 errorId" ASSERT_EQUALS("7 errorId"
"5 error" "5 error"
"1 0"
"12 inconclusive" "12 inconclusive"
"17 Programming error" "17 Programming error"
"17 Programming error" "17 Programming error"
@ -272,11 +273,12 @@ private:
std::list<ErrorLogger::ErrorMessage::FileLocation> locs; std::list<ErrorLogger::ErrorMessage::FileLocation> locs;
ErrorMessage msg(locs, Severity::error, std::string("Illegal character in \"foo\001bar\""), "errorId", false); ErrorMessage msg(locs, Severity::error, std::string("Illegal character in \"foo\001bar\""), "errorId", false);
ASSERT_EQUALS(std::string("7 errorId") + ASSERT_EQUALS("7 errorId"
std::string("5 error") + "5 error"
std::string("33 Illegal character in \"foo\\001bar\"") + "1 0"
std::string("33 Illegal character in \"foo\\001bar\"") + "33 Illegal character in \"foo\\001bar\""
std::string("0 "), msg.serialize()); "33 Illegal character in \"foo\\001bar\""
"0 ", msg.serialize());
ErrorMessage msg2; ErrorMessage msg2;
msg2.deserialize(msg.serialize()); msg2.deserialize(msg.serialize());