From cc6d823b2f716a6c3f7ca5767e07431cb0818895 Mon Sep 17 00:00:00 2001 From: Daniel Alley Date: Fri, 27 Oct 2023 21:42:53 -0400 Subject: [PATCH] Convert FileDigest to struct to simplify implementations --- src/constants.rs | 2 +- src/rpm/headers/header.rs | 49 ++++++++++++++------------------------- src/rpm/package.rs | 2 +- src/tests.rs | 8 +++++-- 4 files changed, 26 insertions(+), 35 deletions(-) diff --git a/src/constants.rs b/src/constants.rs index 364efb3d..21098307 100644 --- a/src/constants.rs +++ b/src/constants.rs @@ -558,7 +558,7 @@ bitflags! { // should be equivalent the value mapping used by `pgp::crypto::hash::HashAlgorithm` // but we have to copy it as not everyone uses the `signature` feature #[repr(u32)] -#[derive(Debug, Clone, Copy, enum_primitive_derive::Primitive)] +#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, enum_primitive_derive::Primitive)] pub enum DigestAlgorithm { Md5 = 1, Sha2_256 = 8, diff --git a/src/rpm/headers/header.rs b/src/rpm/headers/header.rs index 4ac28c75..d74a3a57 100644 --- a/src/rpm/headers/header.rs +++ b/src/rpm/headers/header.rs @@ -383,50 +383,37 @@ pub struct FileOwnership { } #[derive(Debug, Clone, Hash, Eq, PartialEq)] -pub enum FileDigest { - Md5(Vec), - Sha2_224(Vec), - Sha2_256(Vec), - Sha2_384(Vec), - Sha2_512(Vec), +pub struct FileDigest { + digest: String, + algo: DigestAlgorithm, // @todo unsupported other types for now } impl FileDigest { - pub fn load_from_str( - algorithm: DigestAlgorithm, - stringly_data: impl AsRef, - ) -> Result { - let hex: Vec = hex::decode(stringly_data.as_ref())?; + pub fn new(algorithm: DigestAlgorithm, hex_digest: impl ToString) -> Result { + let hex = hex_digest.to_string(); + let digest = FileDigest { + digest: hex, + algo: algorithm, + }; + Ok(match algorithm { - DigestAlgorithm::Md5 if hex.len() == 16 => FileDigest::Md5(hex), - DigestAlgorithm::Sha2_256 if hex.len() == 32 => FileDigest::Sha2_256(hex), - DigestAlgorithm::Sha2_224 if hex.len() == 30 => FileDigest::Sha2_224(hex), - DigestAlgorithm::Sha2_384 if hex.len() == 48 => FileDigest::Sha2_384(hex), - DigestAlgorithm::Sha2_512 if hex.len() == 64 => FileDigest::Sha2_512(hex), + DigestAlgorithm::Md5 if digest.digest.len() == 32 => digest, + DigestAlgorithm::Sha2_256 if digest.digest.len() == 64 => digest, + DigestAlgorithm::Sha2_224 if digest.digest.len() == 60 => digest, + DigestAlgorithm::Sha2_384 if digest.digest.len() == 96 => digest, + DigestAlgorithm::Sha2_512 if digest.digest.len() == 128 => digest, // @todo disambiguate mismatch of length from unsupported algorithm digest_algo => return Err(Error::UnsupportedDigestAlgorithm(digest_algo)), }) } pub fn algorithm(&self) -> DigestAlgorithm { - match self { - Self::Md5(_) => DigestAlgorithm::Md5, - Self::Sha2_224(_) => DigestAlgorithm::Sha2_224, - Self::Sha2_256(_) => DigestAlgorithm::Sha2_256, - Self::Sha2_384(_) => DigestAlgorithm::Sha2_384, - Self::Sha2_512(_) => DigestAlgorithm::Sha2_512, - } + self.algo } - pub fn as_hex(&self) -> String { - match self { - Self::Md5(d) => hex::encode(d), - Self::Sha2_224(d) => hex::encode(d), - Self::Sha2_256(d) => hex::encode(d), - Self::Sha2_384(d) => hex::encode(d), - Self::Sha2_512(d) => hex::encode(d), - } + pub fn as_hex(&self) -> &str { + self.digest.as_str() } } diff --git a/src/rpm/package.rs b/src/rpm/package.rs index 21c9642f..3ec7a677 100644 --- a/src/rpm/package.rs +++ b/src/rpm/package.rs @@ -895,7 +895,7 @@ impl PackageMetadata { let digest = if digest.is_empty() { None } else { - Some(FileDigest::load_from_str(algorithm, digest)?) + Some(FileDigest::new(algorithm, digest)?) }; let cap = match caps { Some(caps) => caps.get(idx).map(|x| x.to_owned()), diff --git a/src/tests.rs b/src/tests.rs index 4cc3ff43..6da8b8f7 100644 --- a/src/tests.rs +++ b/src/tests.rs @@ -303,8 +303,12 @@ fn test_rpm_header() -> Result<(), Box> { let checksums: Vec<_> = metadata .get_file_entries()? .iter() - .map(|e| e.digest.as_ref().map(|d| d.to_string())) - .map(|d| d.unwrap_or("".to_owned())) + .map(|e| { + e.digest + .as_ref() + .map(|d| d.to_string()) + .unwrap_or("".to_owned()) + }) .collect(); assert_eq!(expected_file_checksums, checksums);