You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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).
relatedLocations[] - A set of locations relevant to this result. Code scanning will link to related locations when they are embedded in the result message. For more information, see the location object.
Note: This feature requires the support for region data to be implemented first: #136
Example of relatedLocations used in SARIF
I'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:
#!/bin/bashecho"I'm innocent script, just pass the name of the directory as parameter and I'll remove it for you..."
DIR_SUFFIX="*"
UNUSED_VAR=""echo"I'm going to remove directory $1/$DIR_SUFFIX"#! FIXME - Call rm -rf $1/$DIR_SUFFIXecho"<img src="foo.png" />"> file.html
files='file1 file2'
combined_file=`cat ${files}`echo"${combined_file}"
rm $1echo$1# Unquoted variables
find . -name *.ogg # Unquoted find/grep patterns
rm "~/my file.txt"# Quoted tilde expansion
v='--verbose="true"'; cmd $v# Literal quotes in variables
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: