{
"$schema": "https://json.schemastore.org/sarif-2.1.0.json",
"version": "2.1.0",
"runs": [
{
"tool": {
"driver": {
"name": "csdiff",
"version": "3.0.3",
"informationUri": "https://github.com/csutils/csdiff",
"rules": [
{
"id": "SHELLCHECK_WARNING: info[SC2035]",
"name": "SC2035",
"properties": {
"tags": [
"ShellCheck"
]
},
"help": {
"text": "Defect reference: https://github.com/koalaman/shellcheck/wiki/SC2035",
"markdown": "Defect reference: [SC2035](https://github.com/koalaman/shellcheck/wiki/SC2035)"
}
},
{
"id": "SHELLCHECK_WARNING: style[SC2006]",
"name": "SC2006",
"properties": {
"tags": [
"ShellCheck"
]
},
"help": {
"text": "Defect reference: https://github.com/koalaman/shellcheck/wiki/SC2006",
"markdown": "Defect reference: [SC2006](https://github.com/koalaman/shellcheck/wiki/SC2006)"
}
},
{
"id": "SHELLCHECK_WARNING: warning[SC2034]",
"name": "SC2034",
"properties": {
"tags": [
"ShellCheck"
]
},
"help": {
"text": "Defect reference: https://github.com/koalaman/shellcheck/wiki/SC2034",
"markdown": "Defect reference: [SC2034](https://github.com/koalaman/shellcheck/wiki/SC2034)"
}
},
{
"id": "SHELLCHECK_WARNING: warning[SC2061]",
"name": "SC2061",
"properties": {
"tags": [
"ShellCheck"
]
},
"help": {
"text": "Defect reference: https://github.com/koalaman/shellcheck/wiki/SC2061",
"markdown": "Defect reference: [SC2061](https://github.com/koalaman/shellcheck/wiki/SC2061)"
}
},
{
"id": "SHELLCHECK_WARNING: warning[SC2088]",
"name": "SC2088",
"properties": {
"tags": [
"ShellCheck"
]
},
"help": {
"text": "Defect reference: https://github.com/koalaman/shellcheck/wiki/SC2088",
"markdown": "Defect reference: [SC2088](https://github.com/koalaman/shellcheck/wiki/SC2088)"
}
},
{
"id": "SHELLCHECK_WARNING: warning[SC2089]",
"name": "SC2089",
"properties": {
"tags": [
"ShellCheck"
]
},
"help": {
"text": "Defect reference: https://github.com/koalaman/shellcheck/wiki/SC2089",
"markdown": "Defect reference: [SC2089](https://github.com/koalaman/shellcheck/wiki/SC2089)"
}
},
{
"id": "SHELLCHECK_WARNING: warning[SC2090]",
"name": "SC2090",
"properties": {
"tags": [
"ShellCheck"
]
},
"help": {
"text": "Defect reference: https://github.com/koalaman/shellcheck/wiki/SC2090",
"markdown": "Defect reference: [SC2090](https://github.com/koalaman/shellcheck/wiki/SC2090)"
}
},
{
"id": "SHELLCHECK_WARNING: warning[SC2140]",
"name": "SC2140",
"properties": {
"tags": [
"ShellCheck"
]
},
"help": {
"text": "Defect reference: https://github.com/koalaman/shellcheck/wiki/SC2140",
"markdown": "Defect reference: [SC2140](https://github.com/koalaman/shellcheck/wiki/SC2140)"
}
}
]
}
},
"results": [
{
"ruleId": "SHELLCHECK_WARNING: warning[SC2034]",
"level": "warning",
"locations": [
{
"id": 0,
"physicalLocation": {
"artifactLocation": {
"uri": "innocent-script.sh"
},
"region": {
"startLine": 6
}
}
}
],
"message": {
"text": "UNUSED_VAR appears unused. Verify use (or export if used externally)."
},
"codeFlows": [
{
"threadFlows": [
{
"locations": [
{
"location": {
"id": 0,
"physicalLocation": {
"artifactLocation": {
"uri": "innocent-script.sh"
},
"region": {
"startLine": 6
}
},
"message": {
"text": "UNUSED_VAR appears unused. Verify use (or export if used externally)."
}
},
"nestingLevel": 0,
"kinds": [
"warning[SC2034]"
]
}
]
}
]
}
]
},
{
"ruleId": "SHELLCHECK_WARNING: warning[SC2140]",
"level": "warning",
"locations": [
{
"id": 0,
"physicalLocation": {
"artifactLocation": {
"uri": "innocent-script.sh"
},
"region": {
"startLine": 12
}
}
}
],
"message": {
"text": "Word is of the form \"A\"B\"C\" (B indicated). Did you mean \"ABC\" or \"A\\\"B\\\"C\"?"
},
"codeFlows": [
{
"threadFlows": [
{
"locations": [
{
"location": {
"id": 0,
"physicalLocation": {
"artifactLocation": {
"uri": "innocent-script.sh"
},
"region": {
"startLine": 12
}
},
"message": {
"text": "Word is of the form \"A\"B\"C\" (B indicated). Did you mean \"ABC\" or \"A\\\"B\\\"C\"?"
}
},
"nestingLevel": 0,
"kinds": [
"warning[SC2140]"
]
}
]
}
]
}
]
},
{
"ruleId": "SHELLCHECK_WARNING: style[SC2006]",
"locations": [
{
"id": 0,
"physicalLocation": {
"artifactLocation": {
"uri": "innocent-script.sh"
},
"region": {
"startLine": 15
}
}
}
],
"message": {
"text": "Use $(...) notation instead of legacy backticks `...`. Suggestions: use [`$(`](1), use [`)`](2)"
},
"codeFlows": [
{
"threadFlows": [
{
"locations": [
{
"location": {
"id": 0,
"physicalLocation": {
"artifactLocation": {
"uri": "innocent-script.sh"
},
"region": {
"startLine": 15
}
},
"message": {
"text": "Use $(...) notation instead of legacy backticks `...`."
}
},
"nestingLevel": 0,
"kinds": [
"style[SC2006]"
]
}
]
}
]
}
],
"relatedLocations": [
{
"id": 1,
"physicalLocation": {
"artifactLocation": {
"uri": "innocent-script.sh"
},
"region": {
"endColumn": 16,
"endLine": 15,
"startColumn": 15,
"startLine": 15
}
},
"message": {
"text": "$("
}
},
{
"id": 2,
"physicalLocation": {
"artifactLocation": {
"uri": "innocent-script.sh"
},
"region": {
"endColumn": 29,
"endLine": 15,
"startColumn": 28,
"startLine": 15
}
},
"message": {
"text": ")"
}
}
]
},
{
"ruleId": "SHELLCHECK_WARNING: warning[SC2061]",
"level": "warning",
"locations": [
{
"id": 0,
"physicalLocation": {
"artifactLocation": {
"uri": "innocent-script.sh"
},
"region": {
"startLine": 21
}
}
}
],
"message": {
"text": "Quote the parameter to -name so the shell won't interpret it."
},
"codeFlows": [
{
"threadFlows": [
{
"locations": [
{
"location": {
"id": 0,
"physicalLocation": {
"artifactLocation": {
"uri": "innocent-script.sh"
},
"region": {
"startLine": 21
}
},
"message": {
"text": "Quote the parameter to -name so the shell won't interpret it."
}
},
"nestingLevel": 0,
"kinds": [
"warning[SC2061]"
]
}
]
}
]
}
]
},
{
"ruleId": "SHELLCHECK_WARNING: info[SC2035]",
"locations": [
{
"id": 0,
"physicalLocation": {
"artifactLocation": {
"uri": "innocent-script.sh"
},
"region": {
"startLine": 21
}
}
}
],
"message": {
"text": "Use ./*glob* or -- *glob* so names with dashes won't become options."
},
"codeFlows": [
{
"threadFlows": [
{
"locations": [
{
"location": {
"id": 0,
"physicalLocation": {
"artifactLocation": {
"uri": "innocent-script.sh"
},
"region": {
"startLine": 21
}
},
"message": {
"text": "Use ./*glob* or -- *glob* so names with dashes won't become options."
}
},
"nestingLevel": 0,
"kinds": [
"info[SC2035]"
]
}
]
}
]
}
]
},
{
"ruleId": "SHELLCHECK_WARNING: warning[SC2088]",
"level": "warning",
"locations": [
{
"id": 0,
"physicalLocation": {
"artifactLocation": {
"uri": "innocent-script.sh"
},
"region": {
"startLine": 22
}
}
}
],
"message": {
"text": "Tilde does not expand in quotes. Use $HOME."
},
"codeFlows": [
{
"threadFlows": [
{
"locations": [
{
"location": {
"id": 0,
"physicalLocation": {
"artifactLocation": {
"uri": "innocent-script.sh"
},
"region": {
"startLine": 22
}
},
"message": {
"text": "Tilde does not expand in quotes. Use $HOME."
}
},
"nestingLevel": 0,
"kinds": [
"warning[SC2088]"
]
}
]
}
]
}
]
},
{
"ruleId": "SHELLCHECK_WARNING: warning[SC2089]",
"level": "warning",
"locations": [
{
"id": 0,
"physicalLocation": {
"artifactLocation": {
"uri": "innocent-script.sh"
},
"region": {
"startLine": 23
}
}
}
],
"message": {
"text": "Quotes/backslashes will be treated literally. Use an array."
},
"codeFlows": [
{
"threadFlows": [
{
"locations": [
{
"location": {
"id": 0,
"physicalLocation": {
"artifactLocation": {
"uri": "innocent-script.sh"
},
"region": {
"startLine": 23
}
},
"message": {
"text": "Quotes/backslashes will be treated literally. Use an array."
}
},
"nestingLevel": 0,
"kinds": [
"warning[SC2089]"
]
}
]
}
]
}
]
},
{
"ruleId": "SHELLCHECK_WARNING: warning[SC2090]",
"level": "warning",
"locations": [
{
"id": 0,
"physicalLocation": {
"artifactLocation": {
"uri": "innocent-script.sh"
},
"region": {
"startLine": 23
}
}
}
],
"message": {
"text": "Quotes/backslashes in this variable will not be respected."
},
"codeFlows": [
{
"threadFlows": [
{
"locations": [
{
"location": {
"id": 0,
"physicalLocation": {
"artifactLocation": {
"uri": "innocent-script.sh"
},
"region": {
"startLine": 23
}
},
"message": {
"text": "Quotes/backslashes in this variable will not be respected."
}
},
"nestingLevel": 0,
"kinds": [
"warning[SC2090]"
]
}
]
}
]
}
]
}
]
}
]
}
Description
SARIF format allows specifying related locations to the root
defect. GitHub is able to parse this location data and show them in a semi-usable way (examples below).Note: This feature requires the support for
regiondata to be implemented first: #136Example of
relatedLocationsused in SARIFI'm using ShellCheck as an example, but I believe that this might be useful also for other static analyzers.
The shell script used in the example:
{ "ruleId": "SHELLCHECK_WARNING: style[SC2006]", "locations": [ { "id": 0, "physicalLocation": { "artifactLocation": { "uri": "innocent-script.sh" }, "region": { "startLine": 15 } } } ], "message": { "text": "Use $(...) notation instead of legacy backticks `...`." }, "codeFlows": [ { "threadFlows": [ { "locations": [ { "location": { "id": 0, "physicalLocation": { "artifactLocation": { "uri": "innocent-script.sh" }, "region": { "startLine": 15 } }, "message": { "text": "Use $(...) notation instead of legacy backticks `...`. Suggestions: use [`$(`](1), use [`)`](2)" } }, "nestingLevel": 0, "kinds": [ "style[SC2006]" ] } ] } ] } ], "relatedLocations": [ { "id": 1, "physicalLocation": { "artifactLocation": { "uri": "innocent-script.sh" }, "region": { "endColumn": 16, "endLine": 15, "startColumn": 15, "startLine": 15 } }, "message": { "text": "$(" } }, { "id": 2, "physicalLocation": { "artifactLocation": { "uri": "innocent-script.sh" }, "region": { "endColumn": 29, "endLine": 15, "startColumn": 28, "startLine": 15 } }, "message": { "text": ")" } } ] },The GitHub requires links to
relatedLocationsdirectly in themessage.textstring. Otherwise, it doesn't show them in UI.{ "text": "Use $(...) notation instead of legacy backticks `...`. Suggestions: use [`$(`](1), use [`)`](2)" }Data for
relatedLocationscan be gathered when using ShellCheck JSON1 format.{ "file": "innocent-script.sh", "line": 15, "endLine": 15, "column": 15, "endColumn": 29, "level": "style", "code": 2006, "message": "Use $(...) notation instead of legacy backticks `...`.", "fix": { "replacements": [ { "column": 15, "endColumn": 16, "endLine": 15, "insertionPoint": "afterEnd", "line": 15, "precedence": 8, "replacement": "$(" }, { "column": 28, "endColumn": 29, "endLine": 15, "insertionPoint": "beforeStart", "line": 15, "precedence": 8, "replacement": ")" } ] } }Full ShellCheck JSON1
{ "comments": [ { "file": "innocent-script.sh", "line": 6, "endLine": 6, "column": 1, "endColumn": 11, "level": "warning", "code": 2034, "message": "UNUSED_VAR appears unused. Verify use (or export if used externally).", "fix": null }, { "file": "innocent-script.sh", "line": 12, "endLine": 12, "column": 17, "endColumn": 24, "level": "warning", "code": 2140, "message": "Word is of the form \"A\"B\"C\" (B indicated). Did you mean \"ABC\" or \"A\\\"B\\\"C\"?", "fix": null }, { "file": "innocent-script.sh", "line": 15, "endLine": 15, "column": 15, "endColumn": 29, "level": "style", "code": 2006, "message": "Use $(...) notation instead of legacy backticks `...`.", "fix": { "replacements": [ { "column": 15, "endColumn": 16, "endLine": 15, "insertionPoint": "afterEnd", "line": 15, "precedence": 8, "replacement": "$(" }, { "column": 28, "endColumn": 29, "endLine": 15, "insertionPoint": "beforeStart", "line": 15, "precedence": 8, "replacement": ")" } ] } }, { "file": "innocent-script.sh", "line": 21, "endLine": 21, "column": 14, "endColumn": 19, "level": "warning", "code": 2061, "message": "Quote the parameter to -name so the shell won't interpret it.", "fix": null }, { "file": "innocent-script.sh", "line": 21, "endLine": 21, "column": 14, "endColumn": 15, "level": "info", "code": 2035, "message": "Use ./*glob* or -- *glob* so names with dashes won't become options.", "fix": null }, { "file": "innocent-script.sh", "line": 22, "endLine": 22, "column": 5, "endColumn": 18, "level": "warning", "code": 2088, "message": "Tilde does not expand in quotes. Use $HOME.", "fix": null }, { "file": "innocent-script.sh", "line": 23, "endLine": 23, "column": 3, "endColumn": 21, "level": "warning", "code": 2089, "message": "Quotes/backslashes will be treated literally. Use an array.", "fix": null }, { "file": "innocent-script.sh", "line": 23, "endLine": 23, "column": 27, "endColumn": 29, "level": "warning", "code": 2090, "message": "Quotes/backslashes in this variable will not be respected.", "fix": null } ] }Full edited csgrep SARIF
{ "$schema": "https://json.schemastore.org/sarif-2.1.0.json", "version": "2.1.0", "runs": [ { "tool": { "driver": { "name": "csdiff", "version": "3.0.3", "informationUri": "https://github.com/csutils/csdiff", "rules": [ { "id": "SHELLCHECK_WARNING: info[SC2035]", "name": "SC2035", "properties": { "tags": [ "ShellCheck" ] }, "help": { "text": "Defect reference: https://github.com/koalaman/shellcheck/wiki/SC2035", "markdown": "Defect reference: [SC2035](https://github.com/koalaman/shellcheck/wiki/SC2035)" } }, { "id": "SHELLCHECK_WARNING: style[SC2006]", "name": "SC2006", "properties": { "tags": [ "ShellCheck" ] }, "help": { "text": "Defect reference: https://github.com/koalaman/shellcheck/wiki/SC2006", "markdown": "Defect reference: [SC2006](https://github.com/koalaman/shellcheck/wiki/SC2006)" } }, { "id": "SHELLCHECK_WARNING: warning[SC2034]", "name": "SC2034", "properties": { "tags": [ "ShellCheck" ] }, "help": { "text": "Defect reference: https://github.com/koalaman/shellcheck/wiki/SC2034", "markdown": "Defect reference: [SC2034](https://github.com/koalaman/shellcheck/wiki/SC2034)" } }, { "id": "SHELLCHECK_WARNING: warning[SC2061]", "name": "SC2061", "properties": { "tags": [ "ShellCheck" ] }, "help": { "text": "Defect reference: https://github.com/koalaman/shellcheck/wiki/SC2061", "markdown": "Defect reference: [SC2061](https://github.com/koalaman/shellcheck/wiki/SC2061)" } }, { "id": "SHELLCHECK_WARNING: warning[SC2088]", "name": "SC2088", "properties": { "tags": [ "ShellCheck" ] }, "help": { "text": "Defect reference: https://github.com/koalaman/shellcheck/wiki/SC2088", "markdown": "Defect reference: [SC2088](https://github.com/koalaman/shellcheck/wiki/SC2088)" } }, { "id": "SHELLCHECK_WARNING: warning[SC2089]", "name": "SC2089", "properties": { "tags": [ "ShellCheck" ] }, "help": { "text": "Defect reference: https://github.com/koalaman/shellcheck/wiki/SC2089", "markdown": "Defect reference: [SC2089](https://github.com/koalaman/shellcheck/wiki/SC2089)" } }, { "id": "SHELLCHECK_WARNING: warning[SC2090]", "name": "SC2090", "properties": { "tags": [ "ShellCheck" ] }, "help": { "text": "Defect reference: https://github.com/koalaman/shellcheck/wiki/SC2090", "markdown": "Defect reference: [SC2090](https://github.com/koalaman/shellcheck/wiki/SC2090)" } }, { "id": "SHELLCHECK_WARNING: warning[SC2140]", "name": "SC2140", "properties": { "tags": [ "ShellCheck" ] }, "help": { "text": "Defect reference: https://github.com/koalaman/shellcheck/wiki/SC2140", "markdown": "Defect reference: [SC2140](https://github.com/koalaman/shellcheck/wiki/SC2140)" } } ] } }, "results": [ { "ruleId": "SHELLCHECK_WARNING: warning[SC2034]", "level": "warning", "locations": [ { "id": 0, "physicalLocation": { "artifactLocation": { "uri": "innocent-script.sh" }, "region": { "startLine": 6 } } } ], "message": { "text": "UNUSED_VAR appears unused. Verify use (or export if used externally)." }, "codeFlows": [ { "threadFlows": [ { "locations": [ { "location": { "id": 0, "physicalLocation": { "artifactLocation": { "uri": "innocent-script.sh" }, "region": { "startLine": 6 } }, "message": { "text": "UNUSED_VAR appears unused. Verify use (or export if used externally)." } }, "nestingLevel": 0, "kinds": [ "warning[SC2034]" ] } ] } ] } ] }, { "ruleId": "SHELLCHECK_WARNING: warning[SC2140]", "level": "warning", "locations": [ { "id": 0, "physicalLocation": { "artifactLocation": { "uri": "innocent-script.sh" }, "region": { "startLine": 12 } } } ], "message": { "text": "Word is of the form \"A\"B\"C\" (B indicated). Did you mean \"ABC\" or \"A\\\"B\\\"C\"?" }, "codeFlows": [ { "threadFlows": [ { "locations": [ { "location": { "id": 0, "physicalLocation": { "artifactLocation": { "uri": "innocent-script.sh" }, "region": { "startLine": 12 } }, "message": { "text": "Word is of the form \"A\"B\"C\" (B indicated). Did you mean \"ABC\" or \"A\\\"B\\\"C\"?" } }, "nestingLevel": 0, "kinds": [ "warning[SC2140]" ] } ] } ] } ] }, { "ruleId": "SHELLCHECK_WARNING: style[SC2006]", "locations": [ { "id": 0, "physicalLocation": { "artifactLocation": { "uri": "innocent-script.sh" }, "region": { "startLine": 15 } } } ], "message": { "text": "Use $(...) notation instead of legacy backticks `...`. Suggestions: use [`$(`](1), use [`)`](2)" }, "codeFlows": [ { "threadFlows": [ { "locations": [ { "location": { "id": 0, "physicalLocation": { "artifactLocation": { "uri": "innocent-script.sh" }, "region": { "startLine": 15 } }, "message": { "text": "Use $(...) notation instead of legacy backticks `...`." } }, "nestingLevel": 0, "kinds": [ "style[SC2006]" ] } ] } ] } ], "relatedLocations": [ { "id": 1, "physicalLocation": { "artifactLocation": { "uri": "innocent-script.sh" }, "region": { "endColumn": 16, "endLine": 15, "startColumn": 15, "startLine": 15 } }, "message": { "text": "$(" } }, { "id": 2, "physicalLocation": { "artifactLocation": { "uri": "innocent-script.sh" }, "region": { "endColumn": 29, "endLine": 15, "startColumn": 28, "startLine": 15 } }, "message": { "text": ")" } } ] }, { "ruleId": "SHELLCHECK_WARNING: warning[SC2061]", "level": "warning", "locations": [ { "id": 0, "physicalLocation": { "artifactLocation": { "uri": "innocent-script.sh" }, "region": { "startLine": 21 } } } ], "message": { "text": "Quote the parameter to -name so the shell won't interpret it." }, "codeFlows": [ { "threadFlows": [ { "locations": [ { "location": { "id": 0, "physicalLocation": { "artifactLocation": { "uri": "innocent-script.sh" }, "region": { "startLine": 21 } }, "message": { "text": "Quote the parameter to -name so the shell won't interpret it." } }, "nestingLevel": 0, "kinds": [ "warning[SC2061]" ] } ] } ] } ] }, { "ruleId": "SHELLCHECK_WARNING: info[SC2035]", "locations": [ { "id": 0, "physicalLocation": { "artifactLocation": { "uri": "innocent-script.sh" }, "region": { "startLine": 21 } } } ], "message": { "text": "Use ./*glob* or -- *glob* so names with dashes won't become options." }, "codeFlows": [ { "threadFlows": [ { "locations": [ { "location": { "id": 0, "physicalLocation": { "artifactLocation": { "uri": "innocent-script.sh" }, "region": { "startLine": 21 } }, "message": { "text": "Use ./*glob* or -- *glob* so names with dashes won't become options." } }, "nestingLevel": 0, "kinds": [ "info[SC2035]" ] } ] } ] } ] }, { "ruleId": "SHELLCHECK_WARNING: warning[SC2088]", "level": "warning", "locations": [ { "id": 0, "physicalLocation": { "artifactLocation": { "uri": "innocent-script.sh" }, "region": { "startLine": 22 } } } ], "message": { "text": "Tilde does not expand in quotes. Use $HOME." }, "codeFlows": [ { "threadFlows": [ { "locations": [ { "location": { "id": 0, "physicalLocation": { "artifactLocation": { "uri": "innocent-script.sh" }, "region": { "startLine": 22 } }, "message": { "text": "Tilde does not expand in quotes. Use $HOME." } }, "nestingLevel": 0, "kinds": [ "warning[SC2088]" ] } ] } ] } ] }, { "ruleId": "SHELLCHECK_WARNING: warning[SC2089]", "level": "warning", "locations": [ { "id": 0, "physicalLocation": { "artifactLocation": { "uri": "innocent-script.sh" }, "region": { "startLine": 23 } } } ], "message": { "text": "Quotes/backslashes will be treated literally. Use an array." }, "codeFlows": [ { "threadFlows": [ { "locations": [ { "location": { "id": 0, "physicalLocation": { "artifactLocation": { "uri": "innocent-script.sh" }, "region": { "startLine": 23 } }, "message": { "text": "Quotes/backslashes will be treated literally. Use an array." } }, "nestingLevel": 0, "kinds": [ "warning[SC2089]" ] } ] } ] } ] }, { "ruleId": "SHELLCHECK_WARNING: warning[SC2090]", "level": "warning", "locations": [ { "id": 0, "physicalLocation": { "artifactLocation": { "uri": "innocent-script.sh" }, "region": { "startLine": 23 } } } ], "message": { "text": "Quotes/backslashes in this variable will not be respected." }, "codeFlows": [ { "threadFlows": [ { "locations": [ { "location": { "id": 0, "physicalLocation": { "artifactLocation": { "uri": "innocent-script.sh" }, "region": { "startLine": 23 } }, "message": { "text": "Quotes/backslashes in this variable will not be respected." } }, "nestingLevel": 0, "kinds": [ "warning[SC2090]" ] } ] } ] } ] } ] } ] }GitHub UI
Upon clicking on the link with suggestions, the pop-up box shows the location (not visible enough IMHO):
The data can be used to show suggestions in console output as well. For example
sarif-fmttool shows:Related to: