diff --git a/lib/cppcheck.cpp b/lib/cppcheck.cpp index 9c411a8b0af..81c7a28e2e0 100644 --- a/lib/cppcheck.cpp +++ b/lib/cppcheck.cpp @@ -1624,6 +1624,9 @@ void CppCheck::executeAddons(const std::vector& files, const std::s } errmsg.file0 = file0; + if (obj.count("hash")>0) + errmsg.hash = obj["hash"].get(); + mErrorLogger.reportErr(errmsg); } } diff --git a/lib/errorlogger.cpp b/lib/errorlogger.cpp index 17b87cc2c93..c8d7b02dd34 100644 --- a/lib/errorlogger.cpp +++ b/lib/errorlogger.cpp @@ -57,7 +57,7 @@ const std::set ErrorLogger::mCriticalErrorIds{ }; ErrorMessage::ErrorMessage() - : severity(Severity::none), cwe(0U), certainty(Certainty::normal), hash(0) + : severity(Severity::none), cwe(0U), certainty(Certainty::normal) {} // TODO: id and msg are swapped compared to other calls @@ -67,8 +67,7 @@ ErrorMessage::ErrorMessage(std::list callStack, std::string file1, file0(std::move(file1)), severity(severity), // severity for this error message cwe(0U), - certainty(certainty), - hash(0) + certainty(certainty) { // set the summary and verbose messages setmsg(msg); @@ -82,15 +81,14 @@ ErrorMessage::ErrorMessage(std::list callStack, std::string file1, file0(std::move(file1)), severity(severity), // severity for this error message cwe(cwe.id), - certainty(certainty), - hash(0) + certainty(certainty) { // set the summary and verbose messages setmsg(msg); } ErrorMessage::ErrorMessage(const std::list& callstack, const TokenList* list, Severity severity, std::string id, const std::string& msg, Certainty certainty) - : id(std::move(id)), severity(severity), cwe(0U), certainty(certainty), hash(0) + : id(std::move(id)), severity(severity), cwe(0U), certainty(certainty) { // Format callstack for (auto it = callstack.cbegin(); it != callstack.cend(); ++it) { @@ -125,7 +123,7 @@ ErrorMessage::ErrorMessage(const std::list& callstack, const Token setmsg(msg); - hash = 0; // calculateWarningHash(list, hashWarning.str()); + // hash = calculateWarningHash(list, hashWarning.str()); } ErrorMessage::ErrorMessage(ErrorPath errorPath, const TokenList *tokenList, Severity severity, const char id[], const std::string &msg, const CWE &cwe, Certainty certainty) @@ -158,7 +156,7 @@ ErrorMessage::ErrorMessage(ErrorPath errorPath, const TokenList *tokenList, Seve setmsg(msg); - hash = 0; // calculateWarningHash(tokenList, hashWarning.str()); + // hash = calculateWarningHash(tokenList, hashWarning.str()); } ErrorMessage::ErrorMessage(const tinyxml2::XMLElement * const errmsg) diff --git a/lib/errorlogger.h b/lib/errorlogger.h index 5101f765fad..8c88cfbbc9e 100644 --- a/lib/errorlogger.h +++ b/lib/errorlogger.h @@ -179,7 +179,7 @@ class CPPCHECKLIB ErrorMessage { std::string guideline; /** Warning hash */ - std::size_t hash; + std::size_t hash{}; /** set short and verbose messages */ void setmsg(const std::string &msg); diff --git a/lib/sarifreport.cpp b/lib/sarifreport.cpp index 08eddbf8198..4dadc3d5d71 100644 --- a/lib/sarifreport.cpp +++ b/lib/sarifreport.cpp @@ -145,6 +145,11 @@ picojson::array SarifReport::serializeResults() const message["text"] = picojson::value(finding.shortMessage()); res["message"] = picojson::value(message); res["ruleId"] = picojson::value(finding.id); + if (finding.hash != 0) { + picojson::object partialFingerprints; + partialFingerprints["hash/v1"] = picojson::value(std::to_string(finding.hash)); + res["partialFingerprints"] = picojson::value(partialFingerprints); + } results.emplace_back(res); } return results; diff --git a/test/cli/premium_test.py b/test/cli/premium_test.py index b93636880b3..45121819e87 100644 --- a/test/cli/premium_test.py +++ b/test/cli/premium_test.py @@ -163,4 +163,21 @@ def test_help(tmpdir): assert exitcode == 0 assert stdout.startswith('Cppcheck ') # check for product name - TODO: should be "Cppcheck Premium" assert '--premium=' in stdout, stdout # check for premium option - assert 'cppchecksolutions.com' in stdout, stdout # check for premium help link \ No newline at end of file + assert 'cppchecksolutions.com' in stdout, stdout # check for premium help link + + +def test_hash(tmpdir): + # Trac 14225 - warnings with hash + test_file = os.path.join(tmpdir, 'test.c') + addon_file = os.path.join(tmpdir, 'premiumaddon.py') + + with open(test_file, 'wt') as f: + f.write('void foo();\n') + + args = [f"--addon={addon_file}", '--xml', test_file] + + with open(addon_file, 'wt') as f: + f.write('print(\'{"addon":"a","column":1,"errorId":"id","extra":"","file":"test.c","hash":123,"linenr":1,"message":"bug","severity":"error"}\')') + + _, _, stderr = cppcheck(args) + assert '