about summary refs log tree commit diff
path: root/tools/rust-crates-advisory/format-audit-result.jq
blob: 6f230df3f9b075cf307876107297da85a9d0ebc3 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
# This is a jq script to format the JSON output of cargo-audit into a short
# markdown report for humans. It is used by //users/sterni/nixpkgs-crate-holes
# and //tools/rust-crates-advisory:check-all-our-lock-files which will provide
# you with example invocations.
#
# It needs the following arguments passed to it:
#
# - maintainers: Either the empty string or a list of maintainers to @mention
#   for the current lock file.
# - attr: An attribute name (or otherwise unique identifier) to associate the
#   report for the current lock file with.

# Link to human-readable advisory info for a given vulnerability
def link:
  [ "https://rustsec.org/advisories/", .advisory.id, ".html" ] | add;

# Format a list of version constraints
def version_list:
  [ .[] | "`" + . + "`" ] | join("; ");

# show paths to fixing this vulnerability:
#
# - if there are patched releases, show them (the version we are using presumably
#   predates the vulnerability discovery, so we likely want to upgrade to a
#   patched release).
# - if there are no patched releases, show the unaffected versions (in case we
#   want to downgrade).
# - otherwise we state that no unaffected versions are available at this time.
#
# This logic should be useful, but is slightly dumber than cargo-audit's
# suggestion when using the non-JSON output.
def patched:
  if .versions.patched == [] then
    if .versions.unaffected != [] then
       "unaffected: " + (.versions.unaffected | version_list)
    else
      "no unaffected version available"
    end
  else
    "patched: " + (.versions.patched | version_list)
  end;

# if the vulnerability has aliases (like CVE-*) emit them in parens
def aliases:
  if .advisory.aliases == [] then
    ""
  else
    [ " (", (.advisory.aliases | join(", ")), ")" ] | add
  end;

# each vulnerability is rendered as a (normal) sublist item
def format_vulnerability:
  [ "  - "
  , .package.name, " ", .package.version, ": "
  , "[", .advisory.id, "](", link, ")"
  , aliases
  , ", ", patched
  , "\n"
  ] | add;

# be quiet if no found vulnerabilities, otherwise render a GHFM checklist item
if .vulnerabilities.found | not then
  ""
else
  ([ "- [ ] "
   , "`", $attr, "`: "
   , (.vulnerabilities.count | tostring)
   , " vulnerabilities in Cargo.lock"
   , if $maintainers != "" then " (cc " + $maintainers + ")" else "" end
   , "\n"
   ] + (.vulnerabilities.list | map(format_vulnerability))
  ) | add
end