Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -600,7 +600,7 @@ $(libcppdir)/cppcheck.o: lib/cppcheck.cpp externals/picojson/picojson.h external
$(libcppdir)/ctu.o: lib/ctu.cpp externals/tinyxml2/tinyxml2.h lib/astutils.h lib/check.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h lib/xml.h
$(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/ctu.cpp

$(libcppdir)/errorlogger.o: lib/errorlogger.cpp externals/tinyxml2/tinyxml2.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/token.h lib/tokenlist.h lib/utils.h lib/vfvalue.h lib/xml.h
$(libcppdir)/errorlogger.o: lib/errorlogger.cpp externals/tinyxml2/tinyxml2.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenlist.h lib/utils.h lib/vfvalue.h lib/xml.h
$(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/errorlogger.cpp

$(libcppdir)/errortypes.o: lib/errortypes.cpp lib/config.h lib/errortypes.h lib/utils.h
Expand Down
65 changes: 63 additions & 2 deletions lib/errorlogger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include "path.h"
#include "settings.h"
#include "suppressions.h"
#include "symboldatabase.h"
#include "token.h"
#include "tokenlist.h"
#include "utils.h"
Expand All @@ -35,6 +36,7 @@
#include <cstring>
#include <fstream>
#include <iomanip>
#include <numeric>
#include <sstream>
#include <string>
#include <unordered_map>
Expand Down Expand Up @@ -106,6 +108,8 @@ ErrorMessage::ErrorMessage(const std::list<const Token*>& callstack, const Token
file0 = list->getFiles()[0];

setmsg(msg);

calculateWarningHash(callstack);
}


Expand All @@ -126,7 +130,7 @@ ErrorMessage::ErrorMessage(const std::list<const Token*>& callstack, const Token

setmsg(msg);

// hash = calculateWarningHash(list, hashWarning.str());
calculateWarningHash(callstack);
}

ErrorMessage::ErrorMessage(ErrorPath errorPath, const TokenList *tokenList, Severity severity, const char id[], const std::string &msg, const CWE &cwe, Certainty certainty)
Expand Down Expand Up @@ -159,7 +163,12 @@ ErrorMessage::ErrorMessage(ErrorPath errorPath, const TokenList *tokenList, Seve

setmsg(msg);

// hash = calculateWarningHash(tokenList, hashWarning.str());
std::list<const Token*> tokens;
std::transform(errorPath.cbegin(), errorPath.cend(), std::back_inserter(tokens),
[](const ErrorPathItem& e) {
return e.first;
});
calculateWarningHash(tokens);
}

// TODO: improve errorhandling?
Expand Down Expand Up @@ -244,6 +253,58 @@ void ErrorMessage::setmsg(const std::string &msg)
}
}

void ErrorMessage::calculateWarningHash(const std::list<const Token*>& callstack)
{
if (callstack.empty())
return;
// Calculate a hash for this warning message
std::string hashString;
for (const Token* tok: callstack) {
if (!tok)
continue;
if (!tok->scope())
return; // might be a syntax error before scope info has been set
if (tok->scope()->isExecutable()) {
// Executable scope => include all tokens in the function => if the
// function is changed the hash is changed
for (const Token* t = tok; t; t = t->previous()) {
if (!t->scope()->isExecutable())
break;
hashString += " " + t->str();
}
for (const Token* t = tok->next(); t; t = t->next()) {
if (!t->scope()->isExecutable())
break;
hashString += " " + t->str();
}
} else {
// Non executable scope => include tokens in current statement => if the current statement is changed the hash is changed
for (const Token* t = tok; t; t = t->previous()) {
if (t->str() == ";")
break;
if (t->scope() != tok->scope()) // stop on {} unless its an initializer
break;
hashString += " " + t->str();
}
for (const Token* t = tok->next(); t; t = t->next()) {
hashString += " " + t->str();
if (t->str() == ";")
break;
if (t->scope() != tok->scope()) // stop on {} unless its an initializer
break;
}
}
}

hashString = id + '\n' + mShortMessage + '\n' + hashString;

// hash algorithm: sdbm
// any hash algorithm can be used but it has to be the same hash on different platforms and compilers
hash = std::accumulate(hashString.cbegin(), hashString.cend(), std::size_t{0}, [](std::size_t h, unsigned char c) {
return static_cast<std::size_t>(c) + (h << 6) + (h << 16) - h;
});
}

static void serializeString(std::string &oss, const std::string & str)
{
oss += std::to_string(str.length());
Expand Down
2 changes: 2 additions & 0 deletions lib/errorlogger.h
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,8 @@ class CPPCHECKLIB ErrorMessage {
private:
static std::string fixInvalidChars(const std::string& raw);

void calculateWarningHash(const std::list<const Token*>& callstack);

/** Short message */
std::string mShortMessage;

Expand Down
2 changes: 1 addition & 1 deletion oss-fuzz/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,7 @@ $(libcppdir)/cppcheck.o: ../lib/cppcheck.cpp ../externals/picojson/picojson.h ..
$(libcppdir)/ctu.o: ../lib/ctu.cpp ../externals/tinyxml2/tinyxml2.h ../lib/astutils.h ../lib/check.h ../lib/config.h ../lib/ctu.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h ../lib/xml.h
$(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/ctu.cpp

$(libcppdir)/errorlogger.o: ../lib/errorlogger.cpp ../externals/tinyxml2/tinyxml2.h ../lib/check.h ../lib/checkers.h ../lib/color.h ../lib/config.h ../lib/cppcheck.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/standards.h ../lib/suppressions.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h ../lib/xml.h
$(libcppdir)/errorlogger.o: ../lib/errorlogger.cpp ../externals/tinyxml2/tinyxml2.h ../lib/check.h ../lib/checkers.h ../lib/color.h ../lib/config.h ../lib/cppcheck.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/suppressions.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h ../lib/xml.h
$(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/errorlogger.cpp

$(libcppdir)/errortypes.o: ../lib/errortypes.cpp ../lib/config.h ../lib/errortypes.h ../lib/utils.h
Expand Down
2 changes: 1 addition & 1 deletion test/cli/other_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -2666,7 +2666,7 @@ def test_xml_output(tmp_path): # #13391 / #13485
<results version="2">
<cppcheck version="{}"/>
<errors>
<error id="nullPointerRedundantCheck" severity="warning" msg="Either the condition &apos;p&apos; is redundant or there is possible null pointer dereference: p." verbose="Either the condition &apos;p&apos; is redundant or there is possible null pointer dereference: p." cwe="476" file0="{}" remark="boom">
<error id="nullPointerRedundantCheck" severity="warning" msg="Either the condition &apos;p&apos; is redundant or there is possible null pointer dereference: p." verbose="Either the condition &apos;p&apos; is redundant or there is possible null pointer dereference: p." cwe="476" hash="2884341854190588507" file0="{}" remark="boom">
<location file="{}" line="5" column="12" info="Null pointer dereference"/>
<location file="{}" line="4" column="8" info="Assuming that condition &apos;p&apos; is not redundant"/>
<symbol>p</symbol>
Expand Down
Loading