Skip to content

Commit 3734502

Browse files
committed
Tooling: Clean check suite — fix vulns, compact audit output
- Upgrade `rustls-webpki` 0.103.11 → 0.103.12 (fixes RUSTSEC-2026-0098/0099) - Upgrade `bitstream-io` 4.9.0 → 4.10.0 (drops yanked `core2`) - Switch `cargo-audit` to `--json` output, format one line per advisory instead of full dep trees - Add `--ignore` for 26 upstream Tauri/GTK/unic advisories we can't fix - Extract helpers in `cargo-audit` and `file-length` checks to pass gocyclo ≤15 - Remove unused `onDestroy` import in debug page (eslint) - Allowlist `initialization.ts` in coverage (all paths depend on Tauri commands)
1 parent 8d7d744 commit 3734502

5 files changed

Lines changed: 172 additions & 146 deletions

File tree

Cargo.lock

Lines changed: 15 additions & 15 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

apps/desktop/coverage-allowlist.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@
2626
"file-explorer/views/BriefList.svelte": {
2727
"reason": "Logic tested in brief-list-utils.ts, component mounting heavy"
2828
},
29+
"file-explorer/pane/initialization.ts": {
30+
"reason": "All code paths depend on Tauri commands (pathExists, getDefaultVolumeId, resolvePathVolume, getE2eStartPath)"
31+
},
2932
"file-explorer/pane/DialogManager.svelte": {
3033
"reason": "Pure rendering component, dialog state tested via parent"
3134
},

apps/desktop/src/routes/debug/+page.svelte

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<script lang="ts">
2-
import { onMount, onDestroy, tick } from 'svelte'
2+
import { onMount, tick } from 'svelte'
33
import ToastContainer from '$lib/ui/toast/ToastContainer.svelte'
44
import DebugDriveIndexPanel from './DebugDriveIndexPanel.svelte'
55
import DebugToastPanel from './DebugToastPanel.svelte'

scripts/check/checks/desktop-rust-cargo-audit.go

Lines changed: 102 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,12 @@ import (
99

1010
// cargoAuditReport is the top-level JSON output from `cargo audit --json`.
1111
type cargoAuditReport struct {
12-
Lockfile struct{ DependencyCount int `json:"dependency-count"` } `json:"lockfile"`
12+
Lockfile struct {
13+
DependencyCount int `json:"dependency-count"`
14+
} `json:"lockfile"`
1315
Vulnerabilities struct {
14-
Count int `json:"count"`
15-
List []cargoAuditVulnEntry `json:"list"`
16+
Count int `json:"count"`
17+
List []cargoAuditVulnEntry `json:"list"`
1618
} `json:"vulnerabilities"`
1719
Warnings map[string][]cargoAuditWarningEntry `json:"warnings"`
1820
}
@@ -31,112 +33,143 @@ type cargoAuditWarningEntry struct {
3133
}
3234

3335
type cargoAuditAdvisory struct {
34-
ID string `json:"id"`
35-
Package string `json:"package"`
36-
Title string `json:"title"`
37-
Informational *string `json:"informational"`
36+
ID string `json:"id"`
37+
Title string `json:"title"`
3838
}
3939

4040
type cargoAuditPackage struct {
4141
Name string `json:"name"`
4242
Version string `json:"version"`
4343
}
4444

45-
// RunCargoAudit checks for security vulnerabilities.
46-
func RunCargoAudit(ctx *CheckContext) (CheckResult, error) {
47-
// Check if cargo-audit is installed
48-
if !CommandExists("cargo-audit") {
49-
installCmd := exec.Command("cargo", "install", "cargo-audit")
50-
if _, err := RunCommand(installCmd, true); err != nil {
51-
return CheckResult{}, fmt.Errorf("failed to install cargo-audit: %w", err)
52-
}
53-
}
54-
55-
// Ignore advisories for upstream Tauri dependencies with no fix available:
56-
// RUSTSEC-2023-0071: rsa timing sidechannel (via sspi → smb, no fix released)
57-
// RUSTSEC-2024-0413..0416: gtk-rs GTK3 bindings unmaintained (used by wry/tao)
58-
// RUSTSEC-2024-0421..0424: gtk-sys unmaintained variants
59-
cmd := exec.Command("cargo", "audit", "--json",
60-
"--ignore", "RUSTSEC-2023-0071",
61-
"--ignore", "RUSTSEC-2024-0413",
62-
"--ignore", "RUSTSEC-2024-0414",
63-
"--ignore", "RUSTSEC-2024-0415",
64-
"--ignore", "RUSTSEC-2024-0416",
65-
"--ignore", "RUSTSEC-2024-0421",
66-
"--ignore", "RUSTSEC-2024-0422",
67-
"--ignore", "RUSTSEC-2024-0423",
68-
"--ignore", "RUSTSEC-2024-0424",
69-
)
70-
cmd.Dir = ctx.RootDir
71-
output, _ := RunCommand(cmd, true)
72-
// cargo audit exits non-zero when vulns are found, so we ignore the error
73-
// and parse the JSON output instead.
74-
75-
var report cargoAuditReport
76-
if err := json.Unmarshal([]byte(output), &report); err != nil {
77-
return CheckResult{}, fmt.Errorf("failed to parse cargo-audit JSON output: %w\n%s", err, indentOutput(output))
78-
}
79-
80-
// Count warnings across all categories
81-
totalWarnings := 0
82-
for _, entries := range report.Warnings {
83-
totalWarnings += len(entries)
84-
}
45+
// Advisories for upstream transitive dependencies with no fix available.
46+
// All of these are pulled in by Tauri/wry/tao and can't be resolved by us.
47+
var cargoAuditIgnoredAdvisories = []string{
48+
"RUSTSEC-2023-0071", // rsa timing sidechannel (via sspi → smb, no fix released)
49+
"RUSTSEC-2024-0370", // proc-macro-error unmaintained (via gtk3-macros, glib-macros)
50+
"RUSTSEC-2024-0411", // gdkwayland-sys unmaintained
51+
"RUSTSEC-2024-0412", // gdk unmaintained
52+
"RUSTSEC-2024-0413", // gtk-rs GTK3 unmaintained
53+
"RUSTSEC-2024-0414", // gtk-rs GTK3 unmaintained
54+
"RUSTSEC-2024-0415", // gtk-rs GTK3 unmaintained
55+
"RUSTSEC-2024-0416", // gtk-rs GTK3 unmaintained
56+
"RUSTSEC-2024-0417", // gdkx11 unmaintained
57+
"RUSTSEC-2024-0418", // gdk-sys unmaintained
58+
"RUSTSEC-2024-0419", // gtk3-macros unmaintained
59+
"RUSTSEC-2024-0420", // gtk-sys unmaintained
60+
"RUSTSEC-2024-0421", // gtk-sys unmaintained
61+
"RUSTSEC-2024-0422", // gtk-sys unmaintained
62+
"RUSTSEC-2024-0423", // gtk-sys unmaintained
63+
"RUSTSEC-2024-0424", // gtk-sys unmaintained
64+
"RUSTSEC-2024-0429", // glib unsound VariantStrIter (via GTK3 bindings)
65+
"RUSTSEC-2024-0436", // paste unmaintained (via rav1e → ravif → image)
66+
"RUSTSEC-2025-0052", // async-std unmaintained (dev-dep only, not shipped)
67+
"RUSTSEC-2025-0057", // fxhash unmaintained (via tauri-utils → kuchikiki)
68+
"RUSTSEC-2025-0075", // unic-char-range unmaintained (via tauri-utils → urlpattern)
69+
"RUSTSEC-2025-0080", // unic-common unmaintained
70+
"RUSTSEC-2025-0081", // unic-char-property unmaintained
71+
"RUSTSEC-2025-0098", // unic-ucd-version unmaintained
72+
"RUSTSEC-2025-0100", // unic-ucd-ident unmaintained
73+
"RUSTSEC-2026-0097", // rand unsound (0.7/0.8, not using rand::rng())
74+
}
8575

86-
// No issues at all
87-
if report.Vulnerabilities.Count == 0 && totalWarnings == 0 {
88-
return Success(fmt.Sprintf("Scanned %d %s",
89-
report.Lockfile.DependencyCount,
90-
Pluralize(report.Lockfile.DependencyCount, "crate", "crates"),
91-
)), nil
76+
// buildCargoAuditCmd constructs the cargo audit command with --json and all ignores.
77+
func buildCargoAuditCmd() *exec.Cmd {
78+
args := []string{"audit", "--json"}
79+
for _, id := range cargoAuditIgnoredAdvisories {
80+
args = append(args, "--ignore", id)
9281
}
82+
return exec.Command("cargo", args...)
83+
}
9384

94-
// Build compact summary
85+
// formatAuditReport builds a compact one-line-per-advisory summary.
86+
func formatAuditReport(report cargoAuditReport) string {
9587
var lines []string
9688

97-
// Header line
89+
// Header
9890
var parts []string
9991
if report.Vulnerabilities.Count > 0 {
10092
parts = append(parts, fmt.Sprintf("%d %s",
10193
report.Vulnerabilities.Count,
102-
Pluralize(report.Vulnerabilities.Count, "vulnerability", "vulnerabilities"),
103-
))
94+
Pluralize(report.Vulnerabilities.Count, "vulnerability", "vulnerabilities")))
10495
}
96+
totalWarnings := countAuditWarnings(report)
10597
if totalWarnings > 0 {
10698
parts = append(parts, fmt.Sprintf("%d %s",
107-
totalWarnings,
108-
Pluralize(totalWarnings, "warning", "warnings"),
109-
))
99+
totalWarnings, Pluralize(totalWarnings, "warning", "warnings")))
110100
}
111-
lines = append(lines, strings.Join(parts, ", "))
112-
lines = append(lines, "")
101+
lines = append(lines, strings.Join(parts, ", "), "")
113102

114-
// Vulnerabilities
115103
for _, v := range report.Vulnerabilities.List {
116-
lines = append(lines, fmt.Sprintf("VULN %s %s — %s",
117-
v.Package.Name, v.Package.Version, v.Advisory.Title))
104+
lines = append(lines, fmt.Sprintf("VULN %s %s — %s", v.Package.Name, v.Package.Version, v.Advisory.Title))
118105
fix := "no fix available"
119106
if len(v.Versions.Patched) > 0 {
120107
fix = "upgrade to " + strings.Join(v.Versions.Patched, " or ")
121108
}
122109
lines = append(lines, fmt.Sprintf(" %s | %s", fix, v.Advisory.ID))
123110
}
124-
125-
// Warnings by category
126111
for kind, entries := range report.Warnings {
127112
for _, w := range entries {
128113
lines = append(lines, fmt.Sprintf("WARN %s %s — %s: %s (%s)",
129114
w.Package.Name, w.Package.Version, kind, w.Advisory.Title, w.Advisory.ID))
130115
}
131116
}
117+
return strings.Join(lines, "\n")
118+
}
132119

133-
summary := strings.Join(lines, "\n")
120+
func countAuditWarnings(report cargoAuditReport) int {
121+
total := 0
122+
for _, entries := range report.Warnings {
123+
total += len(entries)
124+
}
125+
return total
126+
}
127+
128+
// parseAuditJSON extracts and parses the JSON object from cargo-audit output.
129+
// RunCommand concatenates stderr after stdout, so we find the JSON boundaries.
130+
func parseAuditJSON(output string) (cargoAuditReport, error) {
131+
jsonStart := strings.Index(output, "{")
132+
jsonEnd := strings.LastIndex(output, "}")
133+
if jsonStart < 0 || jsonEnd < 0 || jsonEnd < jsonStart {
134+
return cargoAuditReport{}, fmt.Errorf("no JSON found in cargo-audit output\n%s", indentOutput(output))
135+
}
136+
var report cargoAuditReport
137+
if err := json.Unmarshal([]byte(output[jsonStart:jsonEnd+1]), &report); err != nil {
138+
return cargoAuditReport{}, fmt.Errorf("failed to parse cargo-audit JSON: %w\n%s", err, indentOutput(output))
139+
}
140+
return report, nil
141+
}
142+
143+
// RunCargoAudit checks for security vulnerabilities.
144+
func RunCargoAudit(ctx *CheckContext) (CheckResult, error) {
145+
if !CommandExists("cargo-audit") {
146+
installCmd := exec.Command("cargo", "install", "cargo-audit")
147+
if _, err := RunCommand(installCmd, true); err != nil {
148+
return CheckResult{}, fmt.Errorf("failed to install cargo-audit: %w", err)
149+
}
150+
}
151+
152+
cmd := buildCargoAuditCmd()
153+
cmd.Dir = ctx.RootDir
154+
output, _ := RunCommand(cmd, true)
155+
156+
report, err := parseAuditJSON(output)
157+
if err != nil {
158+
return CheckResult{}, err
159+
}
160+
161+
if report.Vulnerabilities.Count == 0 && countAuditWarnings(report) == 0 {
162+
return Success(fmt.Sprintf("Scanned %d %s",
163+
report.Lockfile.DependencyCount,
164+
Pluralize(report.Lockfile.DependencyCount, "crate", "crates"))), nil
165+
}
134166

167+
summary := formatAuditReport(report)
135168
if report.Vulnerabilities.Count > 0 {
136169
return CheckResult{}, fmt.Errorf("security vulnerabilities found\n%s", indentOutput(summary))
137170
}
138171

139-
// Warnings only — not a failure
172+
totalWarnings := countAuditWarnings(report)
140173
return CheckResult{
141174
Code: ResultWarning,
142175
Message: fmt.Sprintf("%d %s\n%s", totalWarnings, Pluralize(totalWarnings, "warning", "warnings"), indentOutput(summary)),

0 commit comments

Comments
 (0)