2121
2222#include " abstract-tree.hh"
2323#include " csparser.hh" // for KeyEventDigger
24+ #include " parser-common.hh"
25+ #include " regex.hh"
2426
2527#include < set>
2628
@@ -76,6 +78,11 @@ class SarifTreeDecoder: public AbstractTreeDecoder {
7678 const pt::ptree *root);
7779
7880 virtual bool readNode (Defect *def, pt::ptree::const_iterator defIter);
81+
82+ private:
83+ std::string singleChecker;
84+ const RE reRuleId =
85+ RE (" (" RE_CHECKER_NAME " ): (" RE_EVENT " )" );
7986};
8087
8188struct JsonParser ::Private {
@@ -374,6 +381,17 @@ void SarifTreeDecoder::readScanProps(
374381 TScanProps *pDst,
375382 const pt::ptree *root)
376383{
384+ // read external properties if available
385+ const pt::ptree *iep;
386+ if (findChildOf (&iep, *root, " inlineExternalProperties" )
387+ && (1U == iep->size ()))
388+ {
389+ const pt::ptree *props;
390+ if (findChildOf (&props, iep->begin ()->second , " externalizedProperties" ))
391+ for (const pt::ptree::value_type &item : *props)
392+ (*pDst)[item.first ] = item.second .data ();
393+ }
394+
377395 // check that we have exactly one run
378396 const pt::ptree *runs;
379397 if (!findChildOf (&runs, *root, " runs" ) || (1U != runs->size ()))
@@ -388,17 +406,15 @@ void SarifTreeDecoder::readScanProps(
388406 return ;
389407
390408 const auto name = valueOf<std::string>(*driverNode, " name" , " " );
391- if (name != " SnykCode" )
392- // not a supported tool
393- return ;
394-
395- const auto version = valueOf<std::string>(*driverNode, " version" , " " );
396- if (version.empty ())
397- // no version provided
398- return ;
399-
400- // record tool version of Snyk Code
401- (*pDst)[" analyzer-version-snyk-code" ] = version;
409+ if (name == " SnykCode" ) {
410+ // Snyk Code detected!
411+ this ->singleChecker = " SNYK_CODE_WARNING" ;
412+
413+ const auto version = valueOf<std::string>(*driverNode, " version" , " " );
414+ if (!version.empty ())
415+ // record tool version of Snyk Code
416+ (*pDst)[" analyzer-version-snyk-code" ] = version;
417+ }
402418}
403419
404420void SarifTreeDecoder::readRoot (
@@ -444,7 +460,7 @@ bool SarifTreeDecoder::readNode(
444460 pt::ptree::const_iterator defIter)
445461{
446462 // initialize the defect structure
447- *def = Defect (" SNYK_CODE_WARNING " );
463+ *def = Defect (this -> singleChecker );
448464
449465 // the current node representing a single SARIF report
450466 const pt::ptree &defNode = defIter->second ;
@@ -456,8 +472,18 @@ bool SarifTreeDecoder::readNode(
456472
457473 // read "rule" that triggered the report
458474 const auto rule = valueOf<std::string>(defNode, " ruleId" , " " );
459- if (!rule.empty ())
460- keyEvent.event += " [" + rule + " ]" ;
475+ if (!rule.empty ()) {
476+ boost::smatch sm;
477+ if (boost::regex_match (rule, sm, reRuleId)) {
478+ // csdiff format
479+ def->checker = sm[/* checker */ 1 ];
480+ keyEvent.event = sm[/* keyEvent */ 2 ];
481+ }
482+ else {
483+ // Snyk Code etc.
484+ keyEvent.event += " [" + rule + " ]" ;
485+ }
486+ }
461487
462488 // read location
463489 keyEvent.fileName = " <unknown>" ;
0 commit comments