From 3e3fcbf44de8eb21b32f9feaddf837ee7298684a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AE=89=E6=AD=A3=E8=B6=85?= Date: Fri, 22 May 2026 10:45:53 +0800 Subject: [PATCH] fix(utils): cover sha256 checksum validation (#3052) * fix(utils): cover sha256 checksum validation * docs: clarify sha256 checksum validation --- crates/utils/Cargo.toml | 2 +- crates/utils/src/crypto.rs | 18 +++++++++++++++--- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/crates/utils/Cargo.toml b/crates/utils/Cargo.toml index 60f2cea83..d7ecdd63e 100644 --- a/crates/utils/Cargo.toml +++ b/crates/utils/Cargo.toml @@ -84,7 +84,7 @@ path = [] # path manipulation features notify = ["dep:hyper", "dep:s3s", "dep:hashbrown", "dep:thiserror", "dep:serde", "dep:libc", "dep:url", "dep:regex"] # file system notification features compress = ["dep:flate2", "dep:brotli", "dep:snap", "dep:lz4", "dep:zstd"] string = ["dep:regex"] -crypto = ["dep:base64-simd", "dep:hex-simd", "dep:hmac", "dep:hyper", "dep:sha1"] +crypto = ["dep:base64-simd", "dep:hex-simd", "dep:hmac", "dep:hyper", "dep:sha1", "dep:sha2"] hash = ["dep:highway", "dep:md-5", "dep:sha2", "dep:blake2", "dep:serde", "dep:siphasher", "dep:hex-simd", "dep:crc-fast"] os = ["dep:rustix", "dep:tempfile", "dep:windows"] # operating system utilities integration = [] # integration test features diff --git a/crates/utils/src/crypto.rs b/crates/utils/src/crypto.rs index f8b3d5cc8..b8a4bcc1f 100644 --- a/crates/utils/src/crypto.rs +++ b/crates/utils/src/crypto.rs @@ -66,10 +66,9 @@ pub fn hex(data: impl AsRef<[u8]>) -> String { /// * `s` - A string slice to be verified /// /// # Returns -/// A `bool` indicating whether the input string is a valid SHA-256 checksum (64 -/// +/// A `bool` indicating whether the input string is exactly 64 lowercase hexadecimal characters. +/// Uppercase hexadecimal characters are not accepted. pub fn is_sha256_checksum(s: &str) -> bool { - // TODO: optimize let is_lowercase_hex = |c: u8| matches!(c, b'0'..=b'9' | b'a'..=b'f'); s.len() == 64 && s.as_bytes().iter().copied().all(is_lowercase_hex) } @@ -155,3 +154,16 @@ fn test_base64_encoding_decoding() { assert_eq!(decoded_string, original_uuid_timestamp) } + +#[test] +fn sha256_checksum_accepts_exact_lowercase_hex() { + assert!(is_sha256_checksum("0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef")); +} + +#[test] +fn sha256_checksum_rejects_wrong_length_or_non_lowercase_hex() { + assert!(!is_sha256_checksum("0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcde")); + assert!(!is_sha256_checksum("0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0")); + assert!(!is_sha256_checksum("0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdeg")); + assert!(!is_sha256_checksum("0123456789ABCDEF0123456789abcdef0123456789abcdef0123456789abcdef")); +}