fix(host/windows): clippy — SAFETY comments on the WinTrust FFI, explicit truncate(false), sort_by_key
deb / build-publish-client-arm64 (push) Failing after 4s
ci / docs-site (push) Successful in 1m18s
ci / web (push) Successful in 2m12s
docker / builders (--build-arg FEDORA_VERSION=44, ci/fedora-rpm.Dockerfile, punktfunk-fedora44-rpm, -f44) (push) Successful in 14s
docker / builders (ci/android-ci.Dockerfile, punktfunk-android-ci) (push) Successful in 13s
docker / builders (ci/arch-ci.Dockerfile, punktfunk-arch-ci) (push) Successful in 11s
docker / builders (ci/fedora-rpm.Dockerfile, punktfunk-fedora-rpm) (push) Successful in 10s
docker / builders (ci/rust-ci-noble.Dockerfile, punktfunk-rust-ci-noble) (push) Successful in 11s
docker / builders (ci/rust-ci.Dockerfile, punktfunk-rust-ci) (push) Successful in 8s
docker / apps (., web/Dockerfile, punktfunk-web) (push) Successful in 56s
deb / build-publish-host (push) Successful in 4m28s
docker / apps (docs-site, docs-site/Dockerfile, punktfunk-docs) (push) Successful in 31s
docker / builders-arm64cross (push) Successful in 11s
ci / rust-arm64 (push) Successful in 5m49s
docker / deploy-docs (push) Successful in 31s
android / android (push) Successful in 6m54s
deb / build-publish (push) Successful in 5m0s
apple / swift (push) Successful in 5m6s
ci / rust (push) Successful in 6m13s
arch / build-publish (push) Failing after 7m37s
windows-host / package (push) Successful in 15m8s
windows-host / winget-source (push) Skipped
windows-host / canary-manifest (push) Successful in 41s
rpm / build-publish (44, fedora-44, punktfunk-fedora44-rpm) (push) Successful in 16m40s
rpm / build-publish (43, bazzite, punktfunk-fedora-rpm) (push) Successful in 17m39s
apple / screenshots (push) Successful in 21m28s

windows-host.yml's clippy sees what the Linux gate structurally cannot (cfg(windows)
code); verified with the same clippy line on the runner this time, not just cargo check.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-30 17:42:25 +02:00
co-authored by Claude Fable 5
parent 5790a3e334
commit 696386dee7
+22 -1
View File
@@ -175,6 +175,9 @@ fn download(url: &str, part: &Path, progress: &dyn Fn(u64, Option<u64>)) -> Resu
let mut file = std::fs::OpenOptions::new()
.create(true)
.write(true)
// Never truncate at open: on a 206 we append to the existing partial, and the
// fresh-download path truncates explicitly via `set_len(0)` below.
.truncate(false)
.open(part)
.map_err(|e| format!("open staging file: {e}"))?;
let mut received = if resumed {
@@ -238,6 +241,8 @@ fn preflight_disk(at: &Path, needed: u64) -> Result<(), String> {
use windows::Win32::Storage::FileSystem::GetDiskFreeSpaceExW;
let dir = at.parent().unwrap_or(at);
let mut free: u64 = 0;
// SAFETY: the HSTRING is a valid NUL-terminated path living across the call, and the out
// param points at a live local u64; the API retains neither.
unsafe { GetDiskFreeSpaceExW(&HSTRING::from(dir.as_os_str()), Some(&mut free), None, None) }
.map_err(|e| format!("disk preflight: {e}"))?;
if free < needed {
@@ -286,6 +291,9 @@ pub(crate) fn verify_authenticode(path: &Path, pins: &[String]) -> Result<(), St
};
let mut action: GUID = WINTRUST_ACTION_GENERIC_VERIFY_V2;
// SAFETY: `data`, the `file_info` it points to, and the path's wide buffer all outlive
// the call; `action` is a live mutable GUID. WinVerifyTrust reads the structs and stores
// its state into `data.hWVTStateData`, released by the CLOSE call below.
let status = unsafe {
WinVerifyTrust(
Default::default(),
@@ -308,14 +316,22 @@ pub(crate) fn verify_authenticode(path: &Path, pins: &[String]) -> Result<(), St
return Ok(());
}
// Same-state leaf extraction: no second parse of the file.
// SAFETY: `hWVTStateData` is the live verification state the VERIFY call above
// populated (status checked OK); the returned pointer borrows that state, which stays
// alive until the CLOSE call below, and is null-checked before use.
let prov = unsafe { WTHelperProvDataFromStateData(data.hWVTStateData) };
if prov.is_null() {
return Err("WinVerifyTrust returned no provider state".into());
}
// SAFETY: `prov` was null-checked and borrows the same live verification state;
// index 0 addresses the primary (only) signer, no counter-signer requested.
let signer = unsafe { WTHelperGetProvSignerFromChain(prov, 0, false, 0) };
if signer.is_null() {
return Err("no signer in the Authenticode chain".into());
}
// SAFETY: `signer` was null-checked and borrows the live verification state; the
// chain array is length/null-checked before indexing, and the CERT_CONTEXT borrows
// the same state — every read of it happens before the CLOSE call below.
let leaf = unsafe {
let s = &*signer;
if s.csCertChain == 0 || s.pasCertChain.is_null() {
@@ -324,6 +340,8 @@ pub(crate) fn verify_authenticode(path: &Path, pins: &[String]) -> Result<(), St
// pasCertChain[0] is the SIGNING cert (leaf → root order).
&*(*s.pasCertChain).pCert
};
// SAFETY: `pbCertEncoded`/`cbCertEncoded` describe the DER buffer owned by the live
// cert context above; the slice is consumed (hashed) before the state is closed.
let der =
unsafe { std::slice::from_raw_parts(leaf.pbCertEncoded, leaf.cbCertEncoded as usize) };
let fp = hex(ring::digest::digest(&ring::digest::SHA256, der).as_ref());
@@ -339,6 +357,9 @@ pub(crate) fn verify_authenticode(path: &Path, pins: &[String]) -> Result<(), St
// Always release the verification state.
data.dwStateAction = WTD_STATEACTION_CLOSE;
// SAFETY: same live `data`/`file_info`/`action` as the VERIFY call; CLOSE releases
// `hWVTStateData`, after which no borrow of the state remains (the leaf/DER reads all
// happened inside `verdict` above).
unsafe {
WinVerifyTrust(
Default::default(),
@@ -373,7 +394,7 @@ fn prune_installers(dir: &Path, keep_newest: &Path) {
(t, p)
})
.collect();
exes.sort_by(|a, b| b.0.cmp(&a.0));
exes.sort_by_key(|e| std::cmp::Reverse(e.0));
for (_, p) in exes.into_iter().skip(KEEP_INSTALLERS - 1) {
let _ = std::fs::remove_file(p);
}