Skip to content

Commit c8eb9ab

Browse files
hyperpolymathclaude
andcommitted
fix(security): update rustls-webpki 0.103.10→0.103.13; run cargo fmt
Fixes 3 rustls-webpki CVEs (RUSTSEC-2026-0098, RUSTSEC-2026-0099, RUSTSEC-2026-0104) via ureq→rustls dependency chain. Cargo fmt applied to clear CI formatting gate (no logic changes, 200 tests pass). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 757257c commit c8eb9ab

19 files changed

Lines changed: 471 additions & 247 deletions

Cargo.lock

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

src/assail/analyzer.rs

Lines changed: 94 additions & 74 deletions
Large diffs are not rendered by default.

src/assail/mod.rs

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,7 @@ pub fn analyze<P: AsRef<Path>>(target: P) -> Result<AssailReport> {
3131
let root = if target_ref.is_dir() {
3232
target_ref.to_path_buf()
3333
} else {
34-
target_ref
35-
.parent()
36-
.unwrap_or(Path::new("."))
37-
.to_path_buf()
34+
target_ref.parent().unwrap_or(Path::new(".")).to_path_buf()
3835
};
3936
apply_user_classifications(&mut report, &root);
4037
Ok(report)
@@ -51,14 +48,15 @@ pub fn analyze_verbose<P: AsRef<Path>>(target: P) -> Result<AssailReport> {
5148
let root = if target_ref.is_dir() {
5249
target_ref.to_path_buf()
5350
} else {
54-
target_ref
55-
.parent()
56-
.unwrap_or(Path::new("."))
57-
.to_path_buf()
51+
target_ref.parent().unwrap_or(Path::new(".")).to_path_buf()
5852
};
5953
apply_user_classifications(&mut report, &root);
6054

61-
let active_count = report.weak_points.iter().filter(|wp| !wp.suppressed).count();
55+
let active_count = report
56+
.weak_points
57+
.iter()
58+
.filter(|wp| !wp.suppressed)
59+
.count();
6260
let suppressed_count = report.suppressed_count;
6361

6462
println!("Assail Analysis Complete");
@@ -130,7 +128,11 @@ pub fn analyze_verbose_browser_extension<P: AsRef<Path>>(target: P) -> Result<As
130128
let mut report = analyzer.analyze()?;
131129
apply_suppression(&mut report);
132130

133-
let active_count = report.weak_points.iter().filter(|wp| !wp.suppressed).count();
131+
let active_count = report
132+
.weak_points
133+
.iter()
134+
.filter(|wp| !wp.suppressed)
135+
.count();
134136
let suppressed_count = report.suppressed_count;
135137

136138
println!("Assail Analysis Complete (Browser Extension Mode)");
@@ -559,7 +561,10 @@ mod classifications_tests {
559561

560562
#[test]
561563
fn apply_flips_matching_finding_to_suppressed() {
562-
use crate::types::{AssailReport, AttackAxis, Language, ProgramStatistics, Severity, WeakPoint, WeakPointCategory};
564+
use crate::types::{
565+
AssailReport, AttackAxis, Language, ProgramStatistics, Severity, WeakPoint,
566+
WeakPointCategory,
567+
};
563568
let tmp = TempDir::new().unwrap();
564569
write_registry(
565570
tmp.path(),

src/bridge/classify.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,11 @@ fn classify_reachable(
9797
)
9898
} else if vuln.semver_fix_available {
9999
// Semver-compatible fix — easiest mitigation
100-
let fix_version = vuln.fixed_versions.first().map(String::as_str).unwrap_or("unknown");
100+
let fix_version = vuln
101+
.fixed_versions
102+
.first()
103+
.map(String::as_str)
104+
.unwrap_or("unknown");
101105
(
102106
Classification::Mitigable,
103107
format!(

src/bridge/intelligence.rs

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -180,8 +180,14 @@ fn osv_post_with_retry(body_bytes: &[u8]) -> Result<String> {
180180
match send_result {
181181
Err(e) => {
182182
// Connection-level error — always retry
183-
last_err = anyhow::anyhow!("OSV API request failed (attempt {}): {}", attempt + 1, e);
184-
log::warn!("[bridge] OSV attempt {}/{}: {}", attempt + 1, OSV_MAX_RETRIES, last_err);
183+
last_err =
184+
anyhow::anyhow!("OSV API request failed (attempt {}): {}", attempt + 1, e);
185+
log::warn!(
186+
"[bridge] OSV attempt {}/{}: {}",
187+
attempt + 1,
188+
OSV_MAX_RETRIES,
189+
last_err
190+
);
185191
continue;
186192
}
187193
Ok(mut resp) => {
@@ -195,8 +201,18 @@ fn osv_post_with_retry(body_bytes: &[u8]) -> Result<String> {
195201
.limit(64 * 1024)
196202
.read_to_string()
197203
.unwrap_or_default();
198-
last_err = anyhow::anyhow!("OSV API returned HTTP {} (attempt {}): {}", status, attempt + 1, buf);
199-
log::warn!("[bridge] OSV attempt {}/{}: HTTP {}", attempt + 1, OSV_MAX_RETRIES, status);
204+
last_err = anyhow::anyhow!(
205+
"OSV API returned HTTP {} (attempt {}): {}",
206+
status,
207+
attempt + 1,
208+
buf
209+
);
210+
log::warn!(
211+
"[bridge] OSV attempt {}/{}: HTTP {}",
212+
attempt + 1,
213+
OSV_MAX_RETRIES,
214+
status
215+
);
200216
continue;
201217
}
202218

src/bridge/lockfile.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -442,7 +442,10 @@ sqlalchemy[asyncio]==2.0.0; python_version >= "3.8"
442442
assert!(names.contains(&"flask"));
443443
assert!(names.contains(&"sqlalchemy"));
444444
assert_eq!(
445-
deps.iter().find(|d| d.name == "sqlalchemy").unwrap().version,
445+
deps.iter()
446+
.find(|d| d.name == "sqlalchemy")
447+
.unwrap()
448+
.version,
446449
"2.0.0",
447450
"Env marker should be stripped"
448451
);

src/i18n/catalog.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,7 @@ use serde::{Deserialize, Serialize};
3030
/// Each variant maps to an ISO 639-1 two-letter code. The enum is used by
3131
/// the CLI `--lang` flag and by report generators that emit human-readable
3232
/// text (axial markdown, assault recommendations, adjudicate verdicts).
33-
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
34-
#[derive(Default)]
33+
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, Default)]
3534
pub enum Lang {
3635
#[default]
3736
En,
@@ -121,7 +120,6 @@ impl Lang {
121120
}
122121
}
123122

124-
125123
impl std::fmt::Display for Lang {
126124
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
127125
write!(f, "{}", self.code())

src/kanren/core.rs

Lines changed: 7 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -871,10 +871,7 @@ impl LogicEngine {
871871
"weak_point",
872872
vec![Term::atom("UnsafeCode"), v26.clone(), v27],
873873
),
874-
LogicFact::new(
875-
"context",
876-
vec![v26.clone(), Term::atom("ffi_safe_wrapper")],
877-
),
874+
LogicFact::new("context", vec![v26.clone(), Term::atom("ffi_safe_wrapper")]),
878875
],
879876
RuleMetadata {
880877
confidence: 0.92,
@@ -913,10 +910,7 @@ impl LogicEngine {
913910
"weak_point",
914911
vec![Term::atom("PanicPath"), v28.clone(), v29],
915912
),
916-
LogicFact::new(
917-
"context",
918-
vec![v28.clone(), Term::atom("scanner_source")],
919-
),
913+
LogicFact::new("context", vec![v28.clone(), Term::atom("scanner_source")]),
920914
],
921915
RuleMetadata {
922916
confidence: 0.85,
@@ -1057,8 +1051,8 @@ impl LogicEngine {
10571051
|| path.contains("analyzer")
10581052
|| path.contains("scanner")
10591053
|| path.contains("detector");
1060-
let high_literal_ratio = fs.lines > 0
1061-
&& (fs.unwrap_calls as f64 / fs.lines as f64) >= 0.10;
1054+
let high_literal_ratio =
1055+
fs.lines > 0 && (fs.unwrap_calls as f64 / fs.lines as f64) >= 0.10;
10621056
if is_scanner_path && high_literal_ratio {
10631057
self.db.assert_fact(LogicFact::new(
10641058
"context",
@@ -1682,11 +1676,7 @@ mod tests {
16821676
let mut engine = LogicEngine::new();
16831677
engine.extract_context_facts(&report);
16841678
assert!(
1685-
!has_context(
1686-
&engine,
1687-
"crates/oo7-core/src/plain.rs",
1688-
"ffi_safe_wrapper"
1689-
),
1679+
!has_context(&engine, "crates/oo7-core/src/plain.rs", "ffi_safe_wrapper"),
16901680
"ffi_safe_wrapper=false must not leak the context fact"
16911681
);
16921682
}
@@ -1756,16 +1746,8 @@ mod tests {
17561746
safe_unwrap_calls: 0,
17571747
}],
17581748
vec![
1759-
make_weak_point(
1760-
WeakPointCategory::UnsafeCode,
1761-
path,
1762-
"8 unsafe blocks",
1763-
),
1764-
make_weak_point(
1765-
WeakPointCategory::PanicPath,
1766-
path,
1767-
"20 unwrap/expect calls",
1768-
),
1749+
make_weak_point(WeakPointCategory::UnsafeCode, path, "8 unsafe blocks"),
1750+
make_weak_point(WeakPointCategory::PanicPath, path, "20 unwrap/expect calls"),
17691751
],
17701752
);
17711753
crate::assail::apply_suppression(&mut report);

src/kanren/strategy.rs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -83,11 +83,7 @@ impl SearchStrategy {
8383

8484
/// Compute risk scores for all files and return them in analysis order
8585
pub fn prioritise_files(report: &AssailReport, strategy: SearchStrategy) -> Vec<FileRisk> {
86-
let mut scored: Vec<FileRisk> = report
87-
.file_statistics
88-
.iter()
89-
.map(score_file)
90-
.collect();
86+
let mut scored: Vec<FileRisk> = report.file_statistics.iter().map(score_file).collect();
9187

9288
// Sorting policy is strategy-dependent, but all strategies operate on the same base score set.
9389
match strategy {

src/main.rs

Lines changed: 25 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -2306,38 +2306,36 @@ fn run_main() -> Result<()> {
23062306
return Ok(());
23072307
}
23082308

2309-
Commands::Attest { action } => {
2310-
match action {
2311-
AttestAction::Verify { file } => {
2312-
match attestation::verify_attestation_file(&file)? {
2313-
attestation::VerifyResult::Ok {
2314-
issuer,
2315-
issued_at,
2316-
chain_hash,
2317-
signature_verified,
2318-
} => {
2319-
println!(" [OK] Attestation verified");
2320-
println!(" Issuer: {}", issuer);
2321-
println!(" Issued at: {}", issued_at);
2322-
println!(" Chain: {}", chain_hash);
2323-
if signature_verified {
2324-
println!(" Signature: verified (Ed25519)");
2325-
} else {
2326-
println!(" Signature: not present");
2327-
}
2309+
Commands::Attest { action } => match action {
2310+
AttestAction::Verify { file } => {
2311+
match attestation::verify_attestation_file(&file)? {
2312+
attestation::VerifyResult::Ok {
2313+
issuer,
2314+
issued_at,
2315+
chain_hash,
2316+
signature_verified,
2317+
} => {
2318+
println!(" [OK] Attestation verified");
2319+
println!(" Issuer: {}", issuer);
2320+
println!(" Issued at: {}", issued_at);
2321+
println!(" Chain: {}", chain_hash);
2322+
if signature_verified {
2323+
println!(" Signature: verified (Ed25519)");
2324+
} else {
2325+
println!(" Signature: not present");
23282326
}
2329-
attestation::VerifyResult::Failed(reasons) => {
2330-
eprintln!(" [FAIL] Attestation verification failed:");
2331-
for reason in &reasons {
2332-
eprintln!(" - {}", reason);
2333-
}
2334-
return Err(anyhow::anyhow!("attestation verification failed"));
2327+
}
2328+
attestation::VerifyResult::Failed(reasons) => {
2329+
eprintln!(" [FAIL] Attestation verification failed:");
2330+
for reason in &reasons {
2331+
eprintln!(" - {}", reason);
23352332
}
2333+
return Err(anyhow::anyhow!("attestation verification failed"));
23362334
}
2337-
return Ok(());
23382335
}
2336+
return Ok(());
23392337
}
2340-
}
2338+
},
23412339

23422340
Commands::Temporal { action } => {
23432341
match action {

0 commit comments

Comments
 (0)