Skip to content

Commit 93c3a8f

Browse files
committed
move logic to errorlogger and make generic member
1 parent 5f2195e commit 93c3a8f

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

@@ -212,6 +216,48 @@ ErrorMessage::ErrorMessage(const tinyxml2::XMLElement * const errmsg)
212216
}
213217
}
214218

219+
// Convert instance-specific messages to generic ones
220+
static std::string makeGeneric(const std::string& message)
221+
{
222+
std::string result = message;
223+
224+
// Replace variable names in single quotes with generic terms
225+
result = std::regex_replace(result, std::regex(R"(Variable '[^']*')"), "Variable");
226+
result = std::regex_replace(result, std::regex(R"(variable '[^']*')"), "variable");
227+
result = std::regex_replace(result, std::regex(R"(Function '[^']*')"), "Function");
228+
result = std::regex_replace(result, std::regex(R"(function '[^']*')"), "function");
229+
result = std::regex_replace(result, std::regex(R"(Parameter '[^']*')"), "Parameter");
230+
result = std::regex_replace(result, std::regex(R"(parameter '[^']*')"), "parameter");
231+
result = std::regex_replace(result, std::regex(R"(Member variable '[^']*')"), "Member variable");
232+
result = std::regex_replace(result, std::regex(R"(member variable '[^']*')"), "member variable");
233+
234+
// Replace class::member patterns
235+
result = std::regex_replace(result, std::regex(R"('[^:]*::[^']*')"), "'ClassName::member'");
236+
237+
// Replace specific numbers with generic terms
238+
result = std::regex_replace(result, std::regex(R"(\d+)"), "N");
239+
240+
// Replace array access patterns
241+
result = std::regex_replace(result, std::regex(R"(\[[^\]]+\])"), "[index]");
242+
243+
// Replace remaining single-quoted identifiers
244+
result = std::regex_replace(result, std::regex(R"('[a-zA-Z_][a-zA-Z0-9_]*')"), "'identifier'");
245+
246+
// Clean up redundant patterns
247+
result = std::regex_replace(result, std::regex(R"(Variable 'identifier')"), "Variable");
248+
result = std::regex_replace(result, std::regex(R"(Function 'identifier')"), "Function");
249+
result = std::regex_replace(result, std::regex(R"(Parameter 'identifier')"), "Parameter");
250+
result = std::regex_replace(result, std::regex(R"(Member variable 'identifier')"), "Member variable");
251+
252+
// Clean up multiple spaces
253+
result = std::regex_replace(result, std::regex(R"(\s+)"), " ");
254+
255+
// Trim whitespace
256+
result = std::regex_replace(result, std::regex(R"(^\s+|\s+$)"), "");
257+
258+
return result;
259+
}
260+
215261
void ErrorMessage::setmsg(const std::string &msg)
216262
{
217263
// If a message ends to a '\n' and contains only a one '\n'
@@ -229,12 +275,18 @@ void ErrorMessage::setmsg(const std::string &msg)
229275
if (pos == std::string::npos) {
230276
mShortMessage = replaceStr(msg, "$symbol", symbolName);
231277
mVerboseMessage = replaceStr(msg, "$symbol", symbolName);
278+
// Set generic message (remove symbol names and make generic)
279+
const std::string msgWithoutSymbol = replaceStr(msg, "$symbol", "");
280+
mGenericMessage = makeGeneric(msgWithoutSymbol);
232281
} else if (startsWith(msg,"$symbol:")) {
233282
mSymbolNames += msg.substr(8, pos-7);
234283
setmsg(msg.substr(pos + 1));
235284
} else {
236285
mShortMessage = replaceStr(msg.substr(0, pos), "$symbol", symbolName);
237286
mVerboseMessage = replaceStr(msg.substr(pos + 1), "$symbol", symbolName);
287+
// Set generic message (remove symbol names and make generic)
288+
const std::string msgWithoutSymbol = replaceStr(msg.substr(0, pos), "$symbol", "");
289+
mGenericMessage = makeGeneric(msgWithoutSymbol);
238290
}
239291
}
240292

@@ -285,10 +337,12 @@ std::string ErrorMessage::serialize() const
285337

286338
const std::string saneShortMessage = fixInvalidChars(mShortMessage);
287339
const std::string saneVerboseMessage = fixInvalidChars(mVerboseMessage);
340+
const std::string saneGenericMessage = fixInvalidChars(mGenericMessage);
288341

289342
serializeString(oss, saneShortMessage);
290343
serializeString(oss, saneVerboseMessage);
291344
serializeString(oss, mSymbolNames);
345+
serializeString(oss, saneGenericMessage);
292346
oss += std::to_string(callStack.size());
293347
oss += " ";
294348

@@ -316,9 +370,9 @@ void ErrorMessage::deserialize(const std::string &data)
316370
callStack.clear();
317371

318372
std::istringstream iss(data);
319-
std::array<std::string, 10> results;
373+
std::array<std::string, 11> results;
320374
std::size_t elem = 0;
321-
while (iss.good() && elem < 10) {
375+
while (iss.good() && elem < 11) {
322376
unsigned int len = 0;
323377
if (!(iss >> len))
324378
throw InternalError(nullptr, "Internal Error: Deserialization of error message failed - invalid length");
@@ -344,7 +398,7 @@ void ErrorMessage::deserialize(const std::string &data)
344398
if (!iss.good())
345399
throw InternalError(nullptr, "Internal Error: Deserialization of error message failed - premature end of data");
346400

347-
if (elem != 10)
401+
if (elem != 11)
348402
throw InternalError(nullptr, "Internal Error: Deserialization of error message failed - insufficient elements");
349403

350404
id = std::move(results[0]);
@@ -368,6 +422,7 @@ void ErrorMessage::deserialize(const std::string &data)
368422
mShortMessage = std::move(results[7]);
369423
mVerboseMessage = std::move(results[8]);
370424
mSymbolNames = std::move(results[9]);
425+
mGenericMessage = std::move(results[10]);
371426

372427
unsigned int stackSize = 0;
373428
if (!(iss >> stackSize))
@@ -493,6 +548,8 @@ std::string ErrorMessage::toXML() const
493548
printer.PushAttribute("classification", classification.c_str());
494549
printer.PushAttribute("msg", fixInvalidChars(mShortMessage).c_str());
495550
printer.PushAttribute("verbose", fixInvalidChars(mVerboseMessage).c_str());
551+
if (!mGenericMessage.empty())
552+
printer.PushAttribute("generic", fixInvalidChars(mGenericMessage).c_str());
496553
if (cwe.id)
497554
printer.PushAttribute("cwe", cwe.id);
498555
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)