Skip to content

Commit fd12bf2

Browse files
committed
move logic to errorlogger and make generic member
1 parent e6487ae commit fd12bf2

3 files changed

Lines changed: 79 additions & 3 deletions

File tree

cli/cppcheckexecutor.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -342,11 +342,19 @@ namespace {
342342

343343
static std::string getRuleShortDescription(const ErrorMessage& finding)
344344
{
345+
// Use the generic message if available, otherwise fall back to the original approach
346+
if (!finding.genericMessage().empty()) {
347+
return finding.genericMessage();
348+
}
345349
return SarifRuleCache::getRuleDescription(finding.id, false);
346350
}
347351

348352
static std::string getRuleFullDescription(const ErrorMessage& finding)
349353
{
354+
// Use the generic message if available, otherwise fall back to the original approach
355+
if (!finding.genericMessage().empty()) {
356+
return finding.genericMessage();
357+
}
350358
return SarifRuleCache::getRuleDescription(finding.id, true);
351359
}
352360

lib/errorlogger.cpp

Lines changed: 60 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
#include <string>
4040
#include <unordered_map>
4141
#include <utility>
42+
#include <regex>
4243

4344
#include "xml.h"
4445

@@ -190,6 +191,9 @@ ErrorMessage::ErrorMessage(const tinyxml2::XMLElement * const errmsg)
190191
attr = errmsg->Attribute("verbose");
191192
mVerboseMessage = attr ? attr : "";
192193

194+
attr = errmsg->Attribute("generic");
195+
mGenericMessage = attr ? attr : "";
196+
193197
attr = errmsg->Attribute("hash");
194198
hash = attr ? strToInt<std::size_t>(attr) : 0;
195199

@@ -216,6 +220,48 @@ ErrorMessage::ErrorMessage(const tinyxml2::XMLElement * const errmsg)
216220
}
217221
}
218222

223+
// Convert instance-specific messages to generic ones
224+
static std::string makeGeneric(const std::string& message)
225+
{
226+
std::string result = message;
227+
228+
// Replace variable names in single quotes with generic terms
229+
result = std::regex_replace(result, std::regex(R"(Variable '[^']*')"), "Variable");
230+
result = std::regex_replace(result, std::regex(R"(variable '[^']*')"), "variable");
231+
result = std::regex_replace(result, std::regex(R"(Function '[^']*')"), "Function");
232+
result = std::regex_replace(result, std::regex(R"(function '[^']*')"), "function");
233+
result = std::regex_replace(result, std::regex(R"(Parameter '[^']*')"), "Parameter");
234+
result = std::regex_replace(result, std::regex(R"(parameter '[^']*')"), "parameter");
235+
result = std::regex_replace(result, std::regex(R"(Member variable '[^']*')"), "Member variable");
236+
result = std::regex_replace(result, std::regex(R"(member variable '[^']*')"), "member variable");
237+
238+
// Replace class::member patterns
239+
result = std::regex_replace(result, std::regex(R"('[^:]*::[^']*')"), "'ClassName::member'");
240+
241+
// Replace specific numbers with generic terms
242+
result = std::regex_replace(result, std::regex(R"(\d+)"), "N");
243+
244+
// Replace array access patterns
245+
result = std::regex_replace(result, std::regex(R"(\[[^\]]+\])"), "[index]");
246+
247+
// Replace remaining single-quoted identifiers
248+
result = std::regex_replace(result, std::regex(R"('[a-zA-Z_][a-zA-Z0-9_]*')"), "'identifier'");
249+
250+
// Clean up redundant patterns
251+
result = std::regex_replace(result, std::regex(R"(Variable 'identifier')"), "Variable");
252+
result = std::regex_replace(result, std::regex(R"(Function 'identifier')"), "Function");
253+
result = std::regex_replace(result, std::regex(R"(Parameter 'identifier')"), "Parameter");
254+
result = std::regex_replace(result, std::regex(R"(Member variable 'identifier')"), "Member variable");
255+
256+
// Clean up multiple spaces
257+
result = std::regex_replace(result, std::regex(R"(\s+)"), " ");
258+
259+
// Trim whitespace
260+
result = std::regex_replace(result, std::regex(R"(^\s+|\s+$)"), "");
261+
262+
return result;
263+
}
264+
219265
void ErrorMessage::setmsg(const std::string &msg)
220266
{
221267
// If a message ends to a '\n' and contains only a one '\n'
@@ -233,12 +279,18 @@ void ErrorMessage::setmsg(const std::string &msg)
233279
if (pos == std::string::npos) {
234280
mShortMessage = replaceStr(msg, "$symbol", symbolName);
235281
mVerboseMessage = replaceStr(msg, "$symbol", symbolName);
282+
// Set generic message (remove symbol names and make generic)
283+
const std::string msgWithoutSymbol = replaceStr(msg, "$symbol", "");
284+
mGenericMessage = makeGeneric(msgWithoutSymbol);
236285
} else if (startsWith(msg,"$symbol:")) {
237286
mSymbolNames += msg.substr(8, pos-7);
238287
setmsg(msg.substr(pos + 1));
239288
} else {
240289
mShortMessage = replaceStr(msg.substr(0, pos), "$symbol", symbolName);
241290
mVerboseMessage = replaceStr(msg.substr(pos + 1), "$symbol", symbolName);
291+
// Set generic message (remove symbol names and make generic)
292+
const std::string msgWithoutSymbol = replaceStr(msg.substr(0, pos), "$symbol", "");
293+
mGenericMessage = makeGeneric(msgWithoutSymbol);
242294
}
243295
}
244296

@@ -289,10 +341,12 @@ std::string ErrorMessage::serialize() const
289341

290342
const std::string saneShortMessage = fixInvalidChars(mShortMessage);
291343
const std::string saneVerboseMessage = fixInvalidChars(mVerboseMessage);
344+
const std::string saneGenericMessage = fixInvalidChars(mGenericMessage);
292345

293346
serializeString(oss, saneShortMessage);
294347
serializeString(oss, saneVerboseMessage);
295348
serializeString(oss, mSymbolNames);
349+
serializeString(oss, saneGenericMessage);
296350
oss += std::to_string(callStack.size());
297351
oss += " ";
298352

@@ -320,9 +374,9 @@ void ErrorMessage::deserialize(const std::string &data)
320374
callStack.clear();
321375

322376
std::istringstream iss(data);
323-
std::array<std::string, 10> results;
377+
std::array<std::string, 11> results;
324378
std::size_t elem = 0;
325-
while (iss.good() && elem < 10) {
379+
while (iss.good() && elem < 11) {
326380
unsigned int len = 0;
327381
if (!(iss >> len))
328382
throw InternalError(nullptr, "Internal Error: Deserialization of error message failed - invalid length");
@@ -348,7 +402,7 @@ void ErrorMessage::deserialize(const std::string &data)
348402
if (!iss.good())
349403
throw InternalError(nullptr, "Internal Error: Deserialization of error message failed - premature end of data");
350404

351-
if (elem != 10)
405+
if (elem != 11)
352406
throw InternalError(nullptr, "Internal Error: Deserialization of error message failed - insufficient elements");
353407

354408
id = std::move(results[0]);
@@ -372,6 +426,7 @@ void ErrorMessage::deserialize(const std::string &data)
372426
mShortMessage = std::move(results[7]);
373427
mVerboseMessage = std::move(results[8]);
374428
mSymbolNames = std::move(results[9]);
429+
mGenericMessage = std::move(results[10]);
375430

376431
unsigned int stackSize = 0;
377432
if (!(iss >> stackSize))
@@ -497,6 +552,8 @@ std::string ErrorMessage::toXML() const
497552
printer.PushAttribute("classification", classification.c_str());
498553
printer.PushAttribute("msg", fixInvalidChars(mShortMessage).c_str());
499554
printer.PushAttribute("verbose", fixInvalidChars(mVerboseMessage).c_str());
555+
if (!mGenericMessage.empty())
556+
printer.PushAttribute("generic", fixInvalidChars(mGenericMessage).c_str());
500557
if (cwe.id)
501558
printer.PushAttribute("cwe", cwe.id);
502559
if (hash)

lib/errorlogger.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,14 @@ class CPPCHECKLIB ErrorMessage {
200200
return mSymbolNames;
201201
}
202202

203+
/** Generic message (instance-specific variables replaced with generic terms) */
204+
const std::string &genericMessage() const {
205+
return mGenericMessage;
206+
}
207+
208+
/** set generic message */
209+
void setGenericMessage(const std::string &msg);
210+
203211
static ErrorMessage fromInternalError(const InternalError &internalError, const TokenList *tokenList, const std::string &filename, const std::string& msg = "");
204212

205213
private:
@@ -213,6 +221,9 @@ class CPPCHECKLIB ErrorMessage {
213221

214222
/** symbol names */
215223
std::string mSymbolNames;
224+
225+
/** Generic message */
226+
std::string mGenericMessage;
216227
};
217228

218229
/**

0 commit comments

Comments
 (0)