Skip to content

Commit

Permalink
track a separate "tool" attribute of defects
Browse files Browse the repository at this point in the history
It can be propagated by csdiff's native JSON format and statically
assigned or guessed for the other formats.

Closes: #49
  • Loading branch information
kdudka committed May 5, 2022
1 parent eb60f1b commit d1cb702
Show file tree
Hide file tree
Showing 36 changed files with 14,386 additions and 1 deletion.
1 change: 1 addition & 0 deletions src/csparser.cc
Original file line number Diff line number Diff line change
Expand Up @@ -612,6 +612,7 @@ bool CovParser::Private::parseNext(Defect *def)
this->keDigger.initVerbosity(def);
this->annotHdl.handleDef(def);
this->digger.inferLangFromChecker(def);
this->digger.inferToolFromChecker(def);

// all OK
return true;
Expand Down
1 change: 1 addition & 0 deletions src/defect.hh
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ struct Defect {
int defectId = 0; ///< used only by the JSON format
std::string function; ///< used only by the JSON format
std::string language; ///< used only by the JSON format
std::string tool; ///< used only by the JSON format

Defect() { }

Expand Down
3 changes: 2 additions & 1 deletion src/gcc-parser.cc
Original file line number Diff line number Diff line change
Expand Up @@ -678,7 +678,8 @@ void GccPostProcessor::apply(Defect *pDef) const
d->polishGccAnal(pDef);
d->polishClangAnal(pDef);

d->digger.inferLangFromChecker(pDef);
d->digger.inferLangFromChecker(pDef, /* onlyIfMissing */ false);
d->digger.inferToolFromChecker(pDef, /* onlyIfMissing */ false);
}

struct GccParser::Private {
Expand Down
10 changes: 10 additions & 0 deletions src/json-parser.cc
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,8 @@ class SarifTreeDecoder: public AbstractTreeDecoder {

typedef std::map<std::string, int> TCweMap;
TCweMap cweMap;

ImpliedAttrDigger digger;
};

struct JsonParser::Private {
Expand Down Expand Up @@ -231,6 +233,7 @@ SimpleTreeDecoder::SimpleTreeDecoder(InStream &input):
"imp",
"key_event_idx",
"language",
"tool",
};

// known per-event subnodes
Expand Down Expand Up @@ -312,6 +315,7 @@ bool SimpleTreeDecoder::readNode(
def->imp = valueOf<int> (defNode, "imp" , 0);
def->function = valueOf<std::string>(defNode, "function", "");
def->language = valueOf<std::string>(defNode, "language", "");
def->tool = valueOf<std::string>(defNode, "tool", "");

if (defNode.not_found() == defNode.find("key_event_idx")) {
// key event not specified, try to guess it
Expand Down Expand Up @@ -349,6 +353,9 @@ bool CovTreeDecoder::readNode(
def->function = valueOf<std::string>(defNode, "functionDisplayName", "");
def->language = valueOf<std::string>(defNode, "code-language", "");

// out of the supported tools, only Coverity produces this data format
def->tool = "coverity";

// read CWE if available
const pt::ptree *checkerProps;
if (findChildOf(&checkerProps, defNode, "checkerProperties"))
Expand Down Expand Up @@ -626,5 +633,8 @@ bool SarifTreeDecoder::readNode(
if (findChildOf(&relatedLocs, defNode, "relatedLocations"))
sarifReadComments(def, *relatedLocs);

this->digger.inferLangFromChecker(def);
this->digger.inferToolFromChecker(def);

return true;
}
2 changes: 2 additions & 0 deletions src/json-writer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,8 @@ void SimpleTreeEncoder::appendDef(const Defect &def)
defNode.put<string>("function", def.function);
if (!def.language.empty())
defNode.put<string>("language", def.language);
if (!def.tool.empty())
defNode.put<string>("tool", def.tool);

defNode.put<int>("key_event_idx", def.keyEventIdx);
defNode.put_child("events", evtList);
Expand Down
33 changes: 33 additions & 0 deletions src/parser-common.cc
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@

#include "parser-common.hh"

#include "regex.hh"

#include <boost/algorithm/string.hpp>
#include <boost/algorithm/string/replace.hpp>
#include <boost/lexical_cast.hpp>

int parse_int(const std::string &str, const int fallback)
Expand All @@ -34,6 +38,8 @@ int parse_int(const std::string &str, const int fallback)
struct ImpliedAttrDigger::Private {
typedef std::map<std::string, std::string> TMap;
TMap langByChecker;

const RE reToolWarning = RE("^([A-Z_]+)_WARNING$");
};

ImpliedAttrDigger::ImpliedAttrDigger():
Expand Down Expand Up @@ -70,3 +76,30 @@ void ImpliedAttrDigger::inferLangFromChecker(
// found --> assign from map
pDef->language = it->second;
}

void ImpliedAttrDigger::inferToolFromChecker(
Defect *pDef,
const bool onlyIfMissing)
const
{
if (onlyIfMissing && !pDef->tool.empty())
// tool already assigned
return;

boost::smatch sm;
if (boost::regex_match(pDef->checker, sm, d->reToolWarning)) {
// extract tool="gcc-analyzer" out of checker="GCC_ANALYZER_WARNING"
std::string tool = sm[/* tool */ 1];
boost::algorithm::to_lower(tool);
boost::algorithm::replace_all(tool, "_", "-");

if (tool == "compiler")
// we use COMPILER_WARNING for "gcc" due to historical reasons
tool = "gcc";

pDef->tool = tool;
}
else
// no tool matched --> assume coverity
pDef->tool = "coverity";
}
1 change: 1 addition & 0 deletions src/parser-common.hh
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ class ImpliedAttrDigger {
~ImpliedAttrDigger();

void inferLangFromChecker(Defect *, bool onlyIfMissing = true) const;
void inferToolFromChecker(Defect *, bool onlyIfMissing = true) const;

private:
struct Private;
Expand Down
3 changes: 3 additions & 0 deletions src/xml-parser.cc
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,9 @@ void ValgrindTreeDecoder::readRoot(
// valgrind reports will be at the same level in the XML tree
*pDefList = root;

// only valgrind produces this data format
this->defPrototype.tool = "valgrind";

const int pid = valueOf<int>(*root, "pid", 0);
if (!pid)
// insufficient data
Expand Down
Loading

0 comments on commit d1cb702

Please sign in to comment.