7878#endif
7979
8080namespace {
81- class SarifReport
82- {
81+ class SarifReport {
8382 public:
84- void addFinding (ErrorMessage msg)
85- {
83+ void addFinding (ErrorMessage msg) {
8684 mFindings .push_back (std::move (msg));
8785 }
8886
89- picojson::array serializeRules () const
90- {
87+ picojson::array serializeRules () const {
9188 picojson::array ret;
9289 std::set<std::string> ruleIds;
93- for (const auto & finding : mFindings )
94- {
90+ for (const auto & finding : mFindings ) {
9591 // github only supports findings with locations
9692 if (finding.callStack .empty ())
9793 continue ;
98- if (ruleIds.insert (finding.id ).second )
99- {
94+ if (ruleIds.insert (finding.id ).second ) {
10095 // setting name and description to empty strings will make github default
10196 // to the instance specific violation message and not rule description,
10297 // this makes it so not all the violations have the same description.
10398 picojson::object rule;
104- rule[" id" ] = picojson::value (finding.id );
99+ rule[" id" ] = picojson::value (finding.id );
105100 // rule.name
106101 rule[" name" ] = picojson::value (" " );
107102 // rule.shortDescription.text
@@ -126,35 +121,31 @@ namespace {
126121 if (finding.cwe .id > 0 )
127122 {
128123 double securitySeverity = 0 ;
129- if (finding.severity == Severity::error && !ErrorLogger::isCriticalErrorId (finding.id ))
130- {
124+ if (finding.severity == Severity::error && !ErrorLogger::isCriticalErrorId (finding.id )) {
131125 securitySeverity = 9.9 ; // critical = 9.0+
132126 }
133- else if (finding.severity == Severity::warning)
134- {
127+ else if (finding.severity == Severity::warning) {
135128 securitySeverity = 8.5 ; // high = 7.0 to 8.9
136129 }
137130 else if (finding.severity == Severity::performance || finding.severity == Severity::portability ||
138- finding.severity == Severity::style)
139- {
131+ finding.severity == Severity::style) {
140132 securitySeverity = 5.5 ; // medium = 4.0 to 6.9
141133 }
142134 else if (finding.severity == Severity::information || finding.severity == Severity::internal ||
143- finding.severity == Severity::debug || finding.severity == Severity::none)
144- {
135+ finding.severity == Severity::debug || finding.severity == Severity::none) {
145136 securitySeverity = 2.0 ; // low = 0.1 to 3.9
146137 }
147- if (securitySeverity > 0.0 )
148- {
149- properties[" security-severity" ] = picojson::value (std::to_string (securitySeverity));
138+ if (securitySeverity > 0.0 ) {
139+ std::ostringstream ss;
140+ ss << securitySeverity;
141+ properties[" security-severity" ] = picojson::value (ss.str ());
150142 tags.emplace_back (picojson::value (" external/cwe/cwe-" + std::to_string (finding.cwe .id )));
151143 tags.emplace_back (picojson::value (" security" ));
152144 }
153145 }
154146
155147 // Add tags array if it has any content
156- if (!tags.empty ())
157- {
148+ if (!tags.empty ()) {
158149 properties[" tags" ] = picojson::value (tags);
159150 }
160151
@@ -173,14 +164,12 @@ namespace {
173164 return ret;
174165 }
175166
176- static picojson::array serializeLocations (const ErrorMessage& finding)
177- {
167+ static picojson::array serializeLocations (const ErrorMessage& finding) {
178168 picojson::array ret;
179- for (const auto & location : finding.callStack )
180- {
169+ for (const auto & location : finding.callStack ) {
181170 picojson::object physicalLocation;
182171 picojson::object artifactLocation;
183- artifactLocation[" uri" ] = picojson::value (location.getfile (false ));
172+ artifactLocation[" uri" ] = picojson::value (location.getfile (false ));
184173 physicalLocation[" artifactLocation" ] = picojson::value (artifactLocation);
185174 picojson::object region;
186175
@@ -197,21 +186,19 @@ namespace {
197186 return ret;
198187 }
199188
200- picojson::array serializeResults () const
201- {
189+ picojson::array serializeResults () const {
202190 picojson::array results;
203- for (const auto & finding : mFindings )
204- {
191+ for (const auto & finding : mFindings ) {
205192 // github only supports findings with locations
206193 if (finding.callStack .empty ())
207194 continue ;
208195 picojson::object res;
209- res[" level" ] = picojson::value (sarifSeverity (finding));
196+ res[" level" ] = picojson::value (sarifSeverity (finding));
210197 res[" locations" ] = picojson::value (serializeLocations (finding));
211198 picojson::object message;
212199 message[" text" ] = picojson::value (finding.shortMessage ());
213- res[" message" ] = picojson::value (message);
214- res[" ruleId" ] = picojson::value (finding.id );
200+ res[" message" ] = picojson::value (message);
201+ res[" ruleId" ] = picojson::value (finding.id );
215202 results.emplace_back (res);
216203 }
217204 return results;
@@ -220,39 +207,36 @@ namespace {
220207 picojson::value serializeRuns (const std::string& productName, const std::string& version) const
221208 {
222209 picojson::object driver;
223- driver[" name" ] = picojson::value (productName);
210+ driver[" name" ] = picojson::value (productName);
224211 driver[" semanticVersion" ] = picojson::value (version);
225- driver[" informationUri" ] = picojson::value (" https://cppcheck.sourceforge.io" );
226- driver[" rules" ] = picojson::value (serializeRules ());
212+ driver[" informationUri" ] = picojson::value (" https://cppcheck.sourceforge.io" );
213+ driver[" rules" ] = picojson::value (serializeRules ());
227214 picojson::object tool;
228215 tool[" driver" ] = picojson::value (driver);
229216 picojson::object run;
230- run[" tool" ] = picojson::value (tool);
217+ run[" tool" ] = picojson::value (tool);
231218 run[" results" ] = picojson::value (serializeResults ());
232219 picojson::array runs{picojson::value (run)};
233220 return picojson::value (runs);
234221 }
235222
236- std::string serialize (std::string productName) const
237- {
223+ std::string serialize (std::string productName) const {
238224 const auto nameAndVersion = Settings::getNameAndVersion (productName);
239- productName = nameAndVersion.first .empty () ? " Cppcheck" : nameAndVersion.first ;
240- std::string version = nameAndVersion.first .empty () ? CppCheck::version () : nameAndVersion.second ;
225+ productName = nameAndVersion.first .empty () ? " Cppcheck" : nameAndVersion.first ;
226+ std::string version = nameAndVersion.first .empty () ? CppCheck::version () : nameAndVersion.second ;
241227 if (version.find (' ' ) != std::string::npos)
242228 version.erase (version.find (' ' ), std::string::npos);
243229
244230 picojson::object doc;
245231 doc[" version" ] = picojson::value (" 2.1.0" );
246- doc[" $schema" ] = picojson::value (
247- " https://docs.oasis-open.org/sarif/sarif/v2.1.0/errata01/os/schemas/sarif-schema-2.1.0.json" );
232+ doc[" $schema" ] = picojson::value (" https://docs.oasis-open.org/sarif/sarif/v2.1.0/errata01/os/schemas/sarif-schema-2.1.0.json" );
248233 doc[" runs" ] = serializeRuns (productName, version);
249234
250235 return picojson::value (doc).serialize (true );
251236 }
252237
253238 private:
254- static std::string sarifSeverity (const ErrorMessage& errmsg)
255- {
239+ static std::string sarifSeverity (const ErrorMessage& errmsg) {
256240 if (ErrorLogger::isCriticalErrorId (errmsg.id ))
257241 return " error" ;
258242 switch (errmsg.severity )
@@ -273,8 +257,7 @@ namespace {
273257 return " note" ;
274258 }
275259
276- static std::string sarifPrecision (const ErrorMessage& errmsg)
277- {
260+ static std::string sarifPrecision (const ErrorMessage& errmsg) {
278261 if (errmsg.certainty == Certainty::inconclusive)
279262 return " medium" ;
280263 return " high" ;
0 commit comments