From d045e0f33e95c1d78a384f7d12c2e3861cebb05d Mon Sep 17 00:00:00 2001 From: Ben Boeckel Date: Fri, 10 Jan 2025 14:03:54 +0100 Subject: [PATCH 1/2] clippy: fix `unnecessary-map-or` lints --- git-checks/src/changelog.rs | 2 +- git-checks/src/check_end_of_line.rs | 5 +---- git-checks/src/check_executable_permissions.rs | 2 +- git-checks/src/valid_name.rs | 2 +- 4 files changed, 4 insertions(+), 7 deletions(-) diff --git a/git-checks/src/changelog.rs b/git-checks/src/changelog.rs index 51f23298..4cdce51f 100644 --- a/git-checks/src/changelog.rs +++ b/git-checks/src/changelog.rs @@ -102,7 +102,7 @@ impl ChangelogStyle { let ext_ok = extension.as_ref().map_or(true, |ext| { diff_path .extension() - .map_or(false, |diff_ext| diff_ext == (ext.as_ref() as &Path)) + .is_some_and(|diff_ext| diff_ext == (ext.as_ref() as &Path)) }); ext_ok && diff_path.starts_with(path) diff --git a/git-checks/src/check_end_of_line.rs b/git-checks/src/check_end_of_line.rs index d0da5ada..25887706 100644 --- a/git-checks/src/check_end_of_line.rs +++ b/git-checks/src/check_end_of_line.rs @@ -60,10 +60,7 @@ impl ContentCheck for CheckEndOfLine { }, }; - let has_missing_newline = patch - .lines() - .last() - .map_or(false, |line| line == "\\ No newline at end of file"); + let has_missing_newline = patch.lines().last() == Some("\\ No newline at end of file"); if has_missing_newline { result.add_error(format!( diff --git a/git-checks/src/check_executable_permissions.rs b/git-checks/src/check_executable_permissions.rs index 2960487e..e2fb5064 100644 --- a/git-checks/src/check_executable_permissions.rs +++ b/git-checks/src/check_executable_permissions.rs @@ -106,7 +106,7 @@ impl ContentCheck for CheckExecutablePermissions { true } else { binary_format::detect_binary_format(content) - .map_or(false, |fmt| fmt.is_executable()) + .is_some_and(|fmt| fmt.is_executable()) } }; diff --git a/git-checks/src/valid_name.rs b/git-checks/src/valid_name.rs index 1322baa8..20938c53 100644 --- a/git-checks/src/valid_name.rs +++ b/git-checks/src/valid_name.rs @@ -271,7 +271,7 @@ impl ValidName { } if let Ok(lookup) = Self::check_host(domain) { - lookup.map_or(false, |lookup| { + lookup.is_some_and(|lookup| { let hit = lookup.is_hit(); cache.insert(domain.into(), hit, lookup.cache_duration()); hit -- GitLab From 6158ae0091b98648fa14e5839dc12df5b58164da Mon Sep 17 00:00:00 2001 From: Ben Boeckel Date: Fri, 10 Jan 2025 14:44:30 +0100 Subject: [PATCH 2/2] valid_name: port to `hickory_resolver` The `trust_dns` crate family has been deprecated and yanked. This also allows updating to a version of the `idna` crate that doesn't have RUSTSEC-2024-0421. Also add some `mindeps` tweak dependencies. Fixes: https://rustsec.org/advisories/RUSTSEC-2024-0421 --- .gitlab-ci.yml | 2 +- git-checks-core/Cargo.toml | 2 +- git-checks/CHANGELOG.md | 7 +-- git-checks/Cargo.toml | 13 ++++-- git-checks/src/valid_name.rs | 86 +++++++++++++++++++++++------------- 5 files changed, 70 insertions(+), 40 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 6cc0e03e..f1ef0172 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -14,7 +14,7 @@ stages: - publish .rust_mindeps: - image: "rust:1.64" + image: "rust:1.71" variables: CARGO_UPDATE_POLICY: mindeps diff --git a/git-checks-core/Cargo.toml b/git-checks-core/Cargo.toml index 1bfba644..f0fe0b75 100644 --- a/git-checks-core/Cargo.toml +++ b/git-checks-core/Cargo.toml @@ -24,7 +24,7 @@ rayon = "^1.5" regex = { version = "^1.3.3", default-features = false, features = ["std"] } thiserror = "^1.0.2" -git-workarea = "^4.2.1" +git-workarea = "^4.2.2" # Minimum version fixes. # diff --git a/git-checks/CHANGELOG.md b/git-checks/CHANGELOG.md index b5b3b492..6c61c989 100644 --- a/git-checks/CHANGELOG.md +++ b/git-checks/CHANGELOG.md @@ -2,11 +2,12 @@ ## Updated checks - * The `ValidName` check now performs DNS queries using `trust-dns` instead of - calling out to the system `host` binary. A global DNS resolver using the - system configuration is used. + * The `ValidName` check now performs DNS queries using + `hickory-resolver` instead of calling out to the system `host` binary. + A global DNS resolver using the system configuration is used. * The `InvalidPaths` check now rejects paths which have a restricted Windows pathname as a basename (e.g., `NUL.txt`). + * MSRV bumped to 1.71 to support the `hickory-resolver` crate. # v4.2.2 diff --git a/git-checks/Cargo.toml b/git-checks/Cargo.toml index aaae51d6..d9bda1d9 100644 --- a/git-checks/Cargo.toml +++ b/git-checks/Cargo.toml @@ -11,7 +11,7 @@ documentation = "https://docs.rs/git-checks/~4.2" keywords = ["git", "code-review"] edition = "2018" workspace = ".." -rust-version = "1.64" +rust-version = "1.71" [dev-dependencies] serde_json = "^1.0" @@ -24,8 +24,8 @@ lazy_static = "^1.1" log = "~0.4.4" rayon = "^1.5" thiserror = "^1.0.2" -trust-dns-proto = "~0.23" -trust-dns-resolver = { version = "~0.23", default-features = false, features = ["system-config", "tokio-runtime"] } +hickory-proto = "0.25.0-alpha.4" +hickory-resolver = { version = "0.25.0-alpha.4", default-features = false, features = ["system-config", "tokio-runtime"] } ttl_cache = "~0.5" wait-timeout = "~0.2" @@ -45,7 +45,12 @@ linked-hash-map = "^0.5.3" # https://rustsec.org/advisories/RUSTSEC-2024-0019 mio = "^0.8.11" # Pin to a lower version. -tokio = "~1.30.0" +tokio = { version = "~1.30.0", features = ["rt"] } +# Avoid an old dependency on `idna`. +url = "^2.5.4" +# Avoid transitive dependencies on `failure` and `atty` +web-sys = "~0.3.26" +bumpalo = "^3.11.1" [features] default = [] diff --git a/git-checks/src/valid_name.rs b/git-checks/src/valid_name.rs index 20938c53..e70d42e2 100644 --- a/git-checks/src/valid_name.rs +++ b/git-checks/src/valid_name.rs @@ -14,11 +14,13 @@ use std::time::{Duration, Instant}; use derive_builder::Builder; use git_checks_core::impl_prelude::*; +use hickory_proto::ProtoErrorKind; +use hickory_resolver::name_server::TokioConnectionProvider; +use hickory_resolver::{Name, ResolveError, ResolveErrorKind, Resolver}; use lazy_static::lazy_static; use log::{error, warn}; use thiserror::Error; -use trust_dns_resolver::error::ResolveErrorKind; -use trust_dns_resolver::{Name, Resolver}; +use tokio::runtime::Runtime; use ttl_cache::TtlCache; /// Configuration value for `ValidName` policy for use of full names in identities. @@ -60,7 +62,7 @@ const DEFAULT_TTL_CACHE_MISS_DURATION: Duration = Duration::from_secs(5 * 60); lazy_static! { // DNS resolver. - static ref DNS_RESOLVER: io::Result = Resolver::from_system_conf() + static ref DNS_RESOLVER: Result, ResolveError> = Resolver::tokio_from_system_conf() .map_err(|err| { error!( target: "git-checks/valid_name", @@ -189,19 +191,27 @@ impl HostLookup { enum ValidNameError { #[error("failed to initialize a DNS resolver: {}", reason)] NoResolver { reason: String }, + #[error("failed to start a tokio runtime: {}", source)] + TokioRuntime { source: io::Error }, #[error("failed to parse the domain name: {}", source)] ParseName { #[from] - source: trust_dns_proto::error::ProtoError, + source: hickory_proto::ProtoError, }, } impl ValidNameError { - fn no_resolver(source: &io::Error) -> Self { + fn no_resolver(source: &ResolveError) -> Self { Self::NoResolver { reason: format!("{}", source), } } + + fn tokio_runtime(source: io::Error) -> Self { + Self::TokioRuntime { + source, + } + } } impl ValidName { @@ -221,36 +231,50 @@ impl ValidName { // Search for the absolute domain. let abs_domain = format!("{}.", domain); let name = Name::from_str_relaxed(abs_domain)?; - let lookup = resolver.mx_lookup(name); + let lookup_async = resolver.mx_lookup(name); + + let rt = Runtime::new().map_err(ValidNameError::tokio_runtime)?; + let lookup = rt.block_on(lookup_async); Ok(match lookup { Ok(_) => Some(HostLookup::Hit), Err(err) => { - match err.kind() { - ResolveErrorKind::NoRecordsFound { - negative_ttl, .. - } => { - let valid_until = negative_ttl.and_then(|ttl| { - let ttl_duration = Duration::from_secs(ttl.into()); - let now = Instant::now(); - - now.checked_add(ttl_duration) - }); - Some(HostLookup::Miss { - valid_until, - }) - }, - ResolveErrorKind::Timeout => None, - _ => { - warn!( - target: "git-checks/valid_name", - "failed to look up MX record for domain {}: {:?}", - domain, - err, - ); - - None - }, + if let ResolveErrorKind::Proto(err) = err.kind() { + match err.kind() { + ProtoErrorKind::NoRecordsFound { + negative_ttl, .. + } => { + let valid_until = negative_ttl.and_then(|ttl| { + let ttl_duration = Duration::from_secs(ttl.into()); + let now = Instant::now(); + + now.checked_add(ttl_duration) + }); + Some(HostLookup::Miss { + valid_until, + }) + }, + ProtoErrorKind::Timeout => None, + _ => { + warn!( + target: "git-checks/valid_name", + "failed to look up MX record for domain {} (timeout): {:?}", + domain, + err, + ); + + None + }, + } + } else { + warn!( + target: "git-checks/valid_name", + "failed to look up MX record for domain {}: {:?}", + domain, + err, + ); + + None } }, }) -- GitLab