@@ -153,10 +153,14 @@ class SarifTreeEncoder: public AbstractTreeEncoder {
153
153
154
154
private:
155
155
void initToolVersion ();
156
- void serializeCweMap ();
156
+ void serializeRules ();
157
157
158
- typedef std::map<std::string, int > TCweMap ;
158
+ using TCweMap = std::map<std::string, int >;
159
159
TCweMap cweMap_;
160
+
161
+ using TShellCheckMap = std::map<std::string, std::string>;
162
+ TShellCheckMap shellCheckMap_;
163
+
160
164
TScanProps scanProps_;
161
165
PTree driver_;
162
166
PTree results_;
@@ -215,31 +219,87 @@ void SarifTreeEncoder::initToolVersion()
215
219
driver_.put <std::string>(" informationUri" , uri);
216
220
}
217
221
218
- void SarifTreeEncoder::serializeCweMap ( )
222
+ static void sarifEncodeShellCheckRule (PTree *rule, const std::string &ruleID )
219
223
{
220
- PTree ruleList;
224
+ // name
225
+ rule->put <std::string>(" name" , ruleID);
221
226
222
- for (const auto &item : cweMap_) {
223
- PTree rule;
224
- const auto &id = item.first ;
225
- rule.put <std::string>(" id" , id);
227
+ // properties.tags[]
228
+ PTree tagList;
229
+ appendNode (&tagList, PTree ({" ShellCheck" }));
230
+
231
+ PTree props;
232
+ props.put_child (" tags" , tagList);
233
+ rule->put_child (" properties" , props);
234
+
235
+ // help.text && help.markdown
236
+ PTree help;
237
+ const auto helpURI =
238
+ " https://github.com/koalaman/shellcheck/wiki/" + ruleID;
239
+ help.put <std::string>(" text" , " Defect reference: " + helpURI);
240
+
241
+ const auto helpMarkdown =
242
+ " Defect reference: [" + ruleID +" ](" + helpURI + " )" ;
243
+ help.put <std::string>(" markdown" , helpMarkdown);
226
244
227
- PTree cweList;
228
- const auto cwe = item.second ;
229
- const auto cweStr = std::to_string (cwe);
230
- appendNode (&cweList, PTree (" CWE-" + cweStr));
245
+ rule->put_child (" help" , help);
246
+ }
247
+
248
+ static void sarifEncodeCweRule (PTree *rule, const int cwe, bool append = false )
249
+ {
250
+ PTree cweList;
251
+ const auto cweStr = std::to_string (cwe);
252
+ appendNode (&cweList, PTree (" CWE-" + cweStr));
231
253
232
- // properties.cwe[]
254
+ // properties.cwe[]
255
+ if (append) {
256
+ PTree &props = rule->get_child (" properties" );
257
+ props.put_child (" cwe" , cweList);
258
+ } else {
233
259
PTree props;
234
260
props.put_child (" cwe" , cweList);
235
- rule.put_child (" properties" , props);
261
+ rule->put_child (" properties" , props);
262
+ }
236
263
237
- // help.text
264
+ // help.text
265
+ const auto helpText =
266
+ " https://cwe.mitre.org/data/definitions/" + cweStr + " .html" ;
267
+
268
+ if (append) {
269
+ PTree &help = rule->get_child (" help" );
270
+ const auto &originalHelpText = help.get_child (" text" ).get_value (" " );
271
+ help.put <std::string>(" text" , originalHelpText + ' \n ' + helpText);
272
+ } else {
238
273
PTree help;
239
- const auto helpText =
240
- " https://cwe.mitre.org/data/definitions/" + cweStr + " .html" ;
241
274
help.put <std::string>(" text" , helpText);
242
- rule.put_child (" help" , help);
275
+ rule->put_child (" help" , help);
276
+ }
277
+ }
278
+
279
+ void SarifTreeEncoder::serializeRules ()
280
+ {
281
+ PTree ruleList;
282
+
283
+ for (const auto &item : shellCheckMap_) {
284
+ PTree rule;
285
+ const auto &id = item.first ;
286
+ rule.put <std::string>(" id" , id);
287
+
288
+ sarifEncodeShellCheckRule (&rule, item.second );
289
+ if (1U == cweMap_.count (id))
290
+ sarifEncodeCweRule (&rule, cweMap_[id], /* append =*/ true );
291
+
292
+ appendNode (&ruleList, rule);
293
+ }
294
+
295
+ for (const auto &item : cweMap_) {
296
+ const auto &id = item.first ;
297
+ if (1U == shellCheckMap_.count (id))
298
+ continue ;
299
+
300
+ PTree rule;
301
+ rule.put <std::string>(" id" , id);
302
+ sarifEncodeCweRule (&rule, item.second );
243
303
244
304
appendNode (&ruleList, rule);
245
305
}
@@ -259,7 +319,8 @@ static void sarifEncodeMsg(PTree *pDst, const std::string& text)
259
319
pDst->put_child (" message" , msg);
260
320
}
261
321
262
- static void sarifEncodeLevel (PTree *result, const std::string &event) {
322
+ static void sarifEncodeLevel (PTree *result, const std::string &event)
323
+ {
263
324
std::string level = event;
264
325
265
326
// cut the [...] suffix from event if present
@@ -350,6 +411,16 @@ void SarifTreeEncoder::appendDef(const Defect &def)
350
411
// checker (FIXME: suboptimal mapping to SARIF)
351
412
const std::string ruleId = def.checker + " : " + keyEvt.event ;
352
413
result.put <std::string>(" ruleId" , ruleId);
414
+
415
+ if (def.checker == " SHELLCHECK_WARNING" ) {
416
+ boost::smatch sm;
417
+ static const RE reShellCheckMsg (" (\\ [)?(SC[0-9]+)(\\ ])?$" );
418
+ boost::regex_search (keyEvt.event , sm, reShellCheckMsg);
419
+
420
+ // update ShellCheck rule map
421
+ shellCheckMap_[ruleId] = sm[2 ];
422
+ }
423
+
353
424
if (def.cwe )
354
425
// update CWE map
355
426
cweMap_[ruleId] = def.cwe ;
@@ -423,9 +494,9 @@ void SarifTreeEncoder::writeTo(std::ostream &str)
423
494
424
495
this ->initToolVersion ();
425
496
426
- if (!cweMap_.empty ())
497
+ if (!cweMap_.empty () || !shellCheckMap_. empty () )
427
498
// needs to run before we pick driver_
428
- this ->serializeCweMap ();
499
+ this ->serializeRules ();
429
500
430
501
PTree tool;
431
502
tool.put_child (" driver" , driver_);
0 commit comments