From 698620b6f2b0c0eb7da0df35e6b57762365cbf33 Mon Sep 17 00:00:00 2001 From: chyyran Date: Mon, 8 Aug 2022 23:46:17 -0400 Subject: [PATCH] Update dependencies and adapt to crc v3 API --- Cargo.toml | 8 ++++---- src/decode/util.rs | 23 +++++++++++------------ src/decode/xz.rs | 39 +++++++++++++++++---------------------- src/encode/util.rs | 24 +++++++++++------------- src/encode/xz.rs | 28 ++++++++++++++-------------- src/xz/crc.rs | 4 ++++ src/xz/header.rs | 10 +++++----- src/xz/mod.rs | 1 + 8 files changed, 67 insertions(+), 70 deletions(-) create mode 100644 src/xz/crc.rs diff --git a/Cargo.toml b/Cargo.toml index 63f2566..11b5de5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,10 +12,10 @@ exclude = ["tests/*", "benches/*", "fuzz/*", ".github/*", "Cargo.lock"] edition = "2018" [dependencies] -byteorder = "^1.0.0" -crc = "^1.0.0" -log = { version = "^0.4.14", optional = true } -env_logger = { version = "^0.8.3", optional = true } +byteorder = "1.4.3" +crc = "3.0.0" +log = { version = "0.4.17", optional = true } +env_logger = { version = "0.9.0", optional = true } [dev-dependencies] rust-lzma = "0.5" diff --git a/src/decode/util.rs b/src/decode/util.rs index f00394c..623a870 100644 --- a/src/decode/util.rs +++ b/src/decode/util.rs @@ -1,4 +1,4 @@ -use std::{hash, io}; +use std::io; pub fn read_tag(input: &mut R, tag: &[u8]) -> io::Result { let mut buf = vec![0; tag.len()]; @@ -34,33 +34,32 @@ pub fn flush_zero_padding(input: &mut R) -> io::Result { } // A Read computing a digest on the bytes read. -pub struct HasherRead<'a, R, H> +pub struct CrcDigestRead<'a, 'b, R, S> where R: 'a + io::Read, - H: 'a + hash::Hasher, + S: crc::Width, { - read: &'a mut R, // underlying reader - hasher: &'a mut H, // hasher + read: &'a mut R, // underlying reader + digest: &'a mut crc::Digest<'b, S>, // hasher } -impl<'a, R, H> HasherRead<'a, R, H> +impl<'a, 'b, R, S> CrcDigestRead<'a, 'b, R, S> where R: io::Read, - H: hash::Hasher, + S: crc::Width, { - pub fn new(read: &'a mut R, hasher: &'a mut H) -> Self { - Self { read, hasher } + pub fn new(read: &'a mut R, digest: &'a mut crc::Digest<'b, S>) -> Self { + Self { read, digest } } } -impl<'a, R, H> io::Read for HasherRead<'a, R, H> +impl<'a, 'b, R> io::Read for CrcDigestRead<'a, 'b, R, u32> where R: io::Read, - H: hash::Hasher, { fn read(&mut self, buf: &mut [u8]) -> io::Result { let result = self.read.read(buf)?; - self.hasher.write(&buf[..result]); + self.digest.update(&buf[..result]); Ok(result) } } diff --git a/src/decode/xz.rs b/src/decode/xz.rs index be7d661..a55c855 100644 --- a/src/decode/xz.rs +++ b/src/decode/xz.rs @@ -3,10 +3,9 @@ use crate::decode::lzma2::Lzma2Decoder; use crate::decode::util; use crate::error; +use crate::xz::crc::{CRC32, CRC64}; use crate::xz::{footer, header, CheckMethod, StreamFlags}; use byteorder::{BigEndian, LittleEndian, ReadBytesExt}; -use crc::{crc32, crc64, Hasher32}; -use std::hash::Hasher; use std::io; use std::io::Read; @@ -46,11 +45,9 @@ where }; let crc32 = input.read_u32::()?; - let mut digest = crc32::Digest::new(crc32::IEEE); - + let mut digest = CRC32.digest(); { - let mut digested = util::HasherRead::new(input, &mut digest); - + let mut digested = util::CrcDigestRead::new(input, &mut digest); let backward_size = digested.read_u32::()?; if index_size as u32 != (backward_size + 1) << 2 { return Err(error::Error::XzError(format!( @@ -73,7 +70,7 @@ where } } - let digest_crc32 = digest.sum32(); + let digest_crc32 = digest.finalize(); if crc32 != digest_crc32 { return Err(error::Error::XzError(format!( "Invalid footer CRC32: expected 0x{:08x} but got 0x{:08x}", @@ -103,12 +100,11 @@ fn check_index<'a, R>( where R: io::BufRead, { - let mut digest = crc32::Digest::new(crc32::IEEE); + let mut digest = CRC32.digest(); let index_tag = 0u8; - digest.write_u8(index_tag); - + digest.update(&[index_tag]); { - let mut digested = util::HasherRead::new(count_input, &mut digest); + let mut digested = util::CrcDigestRead::new(count_input, &mut digest); let num_records = get_multibyte(&mut digested)?; if num_records != records.len() as u64 { @@ -138,8 +134,7 @@ where ))); } } - } - + }; // TODO: create padding parser function let count = count_input.count(); let padding_size = ((count ^ 0x03) + 1) & 0x03; @@ -150,7 +145,7 @@ where ); { - let mut digested = util::HasherRead::new(count_input, &mut digest); + let mut digested = util::CrcDigestRead::new(count_input, &mut digest); for _ in 0..padding_size { let byte = digested.read_u8()?; if byte != 0 { @@ -159,9 +154,9 @@ where )); } } - } + }; - let digest_crc32 = digest.sum32(); + let digest_crc32 = digest.finalize(); lzma_info!("XZ index checking digest 0x{:08x}", digest_crc32); let crc32 = count_input.read_u32::()?; @@ -209,18 +204,18 @@ where R: io::BufRead, W: io::Write, { - let mut digest = crc32::Digest::new(crc32::IEEE); - digest.write_u8(header_size); + let mut digest = CRC32.digest(); + digest.update(&[header_size]); let header_size = ((header_size as u64) << 2) - 1; let block_header = { let mut taken = count_input.take(header_size); - let mut digested = io::BufReader::new(util::HasherRead::new(&mut taken, &mut digest)); + let mut digested = io::BufReader::new(util::CrcDigestRead::new(&mut taken, &mut digest)); read_block_header(&mut digested, header_size)? }; let crc32 = count_input.read_u32::()?; - let digest_crc32 = digest.sum32(); + let digest_crc32 = digest.finalize(); if crc32 != digest_crc32 { return Err(error::Error::XzError(format!( "Invalid header CRC32: expected 0x{:08x} but got 0x{:08x}", @@ -309,7 +304,7 @@ where CheckMethod::None => (), CheckMethod::Crc32 => { let crc32 = input.read_u32::()?; - let digest_crc32 = crc32::checksum_ieee(buf); + let digest_crc32 = CRC32.checksum(buf); if crc32 != digest_crc32 { return Err(error::Error::XzError(format!( "Invalid block CRC32, expected 0x{:08x} but got 0x{:08x}", @@ -319,7 +314,7 @@ where } CheckMethod::Crc64 => { let crc64 = input.read_u64::()?; - let digest_crc64 = crc64::checksum_ecma(buf); + let digest_crc64 = CRC64.checksum(buf); if crc64 != digest_crc64 { return Err(error::Error::XzError(format!( "Invalid block CRC64, expected 0x{:016x} but got 0x{:016x}", diff --git a/src/encode/util.rs b/src/encode/util.rs index 3c22e25..625bec1 100644 --- a/src/encode/util.rs +++ b/src/encode/util.rs @@ -1,36 +1,34 @@ -use std::{hash, io}; +use std::io; // A Write computing a digest on the bytes written. -pub struct HasherWrite<'a, W, H> +pub struct CrcDigestWrite<'a, 'b, W, S> where W: 'a + io::Write, - H: 'a + hash::Hasher, + S: crc::Width, { - write: &'a mut W, // underlying writer - hasher: &'a mut H, // hasher + write: &'a mut W, // underlying writer + digest: &'a mut crc::Digest<'b, S>, // hasher } -impl<'a, W, H> HasherWrite<'a, W, H> +impl<'a, 'b, W, S> CrcDigestWrite<'a, 'b, W, S> where W: io::Write, - H: hash::Hasher, + S: crc::Width, { - pub fn new(write: &'a mut W, hasher: &'a mut H) -> Self { - Self { write, hasher } + pub fn new(write: &'a mut W, digest: &'a mut crc::Digest<'b, S>) -> Self { + Self { write, digest } } } -impl<'a, W, H> io::Write for HasherWrite<'a, W, H> +impl<'a, 'b, W> io::Write for CrcDigestWrite<'a, 'b, W, u32> where W: io::Write, - H: hash::Hasher, { fn write(&mut self, buf: &[u8]) -> io::Result { let result = self.write.write(buf)?; - self.hasher.write(&buf[..result]); + self.digest.update(&buf[..result]); Ok(result) } - fn flush(&mut self) -> io::Result<()> { self.write.flush() } diff --git a/src/encode/xz.rs b/src/encode/xz.rs index 1c6a9f6..42bf9ef 100644 --- a/src/encode/xz.rs +++ b/src/encode/xz.rs @@ -1,8 +1,8 @@ use crate::decode; use crate::encode::{lzma2, util}; +use crate::xz::crc::CRC32; use crate::xz::{footer, header, CheckMethod, StreamFlags}; use byteorder::{LittleEndian, WriteBytesExt}; -use crc::{crc32, Hasher32}; use std::io; use std::io::Write; @@ -33,12 +33,12 @@ where W: io::Write, { output.write_all(header::XZ_MAGIC)?; - let mut digest = crc32::Digest::new(crc32::IEEE); + let mut digest = CRC32.digest(); { - let mut digested = util::HasherWrite::new(output, &mut digest); + let mut digested = util::CrcDigestWrite::new(output, &mut digest); stream_flags.serialize(&mut digested)?; } - let crc32 = digest.sum32(); + let crc32 = digest.finalize(); output.write_u32::(crc32)?; Ok(()) } @@ -47,16 +47,16 @@ fn write_footer(output: &mut W, stream_flags: StreamFlags, index_size: usize) where W: io::Write, { - let mut digest = crc32::Digest::new(crc32::IEEE); + let mut digest = CRC32.digest(); let mut footer_buf: Vec = Vec::new(); { - let mut digested = util::HasherWrite::new(&mut footer_buf, &mut digest); + let mut digested = util::CrcDigestWrite::new(&mut footer_buf, &mut digest); let backward_size = (index_size >> 2) - 1; digested.write_u32::(backward_size as u32)?; stream_flags.serialize(&mut digested)?; } - let crc32 = digest.sum32(); + let crc32 = digest.finalize(); output.write_u32::(crc32)?; output.write_all(footer_buf.as_slice())?; @@ -73,9 +73,9 @@ where let mut count_output = util::CountWrite::new(output); // Block header - let mut digest = crc32::Digest::new(crc32::IEEE); + let mut digest = CRC32.digest(); { - let mut digested = util::HasherWrite::new(&mut count_output, &mut digest); + let mut digested = util::CrcDigestWrite::new(&mut count_output, &mut digest); let header_size = 8; digested.write_u8((header_size >> 2) as u8)?; let flags = 0x00; // 1 filter, no (un)packed size provided @@ -89,7 +89,7 @@ where let padding = [0, 0, 0]; digested.write_all(&padding)?; } - let crc32 = digest.sum32(); + let crc32 = digest.finalize(); count_output.write_u32::(crc32)?; // Block @@ -117,9 +117,9 @@ where { let mut count_output = util::CountWrite::new(output); - let mut digest = crc32::Digest::new(crc32::IEEE); + let mut digest = CRC32.digest(); { - let mut digested = util::HasherWrite::new(&mut count_output, &mut digest); + let mut digested = util::CrcDigestWrite::new(&mut count_output, &mut digest); digested.write_u8(0)?; // No more block let num_records = 1; write_multibyte(&mut digested, num_records)?; @@ -132,12 +132,12 @@ where let count = count_output.count(); let padding_size = ((count ^ 0x03) + 1) & 0x03; { - let mut digested = util::HasherWrite::new(&mut count_output, &mut digest); + let mut digested = util::CrcDigestWrite::new(&mut count_output, &mut digest); let padding = vec![0; padding_size]; digested.write_all(padding.as_slice())?; } - let crc32 = digest.sum32(); + let crc32 = digest.finalize(); count_output.write_u32::(crc32)?; Ok(count_output.count()) diff --git a/src/xz/crc.rs b/src/xz/crc.rs new file mode 100644 index 0000000..95e4215 --- /dev/null +++ b/src/xz/crc.rs @@ -0,0 +1,4 @@ +use crc::{Crc, CRC_32_ISO_HDLC, CRC_64_XZ}; + +pub const CRC32: Crc = Crc::::new(&CRC_32_ISO_HDLC); +pub const CRC64: Crc = Crc::::new(&CRC_64_XZ); diff --git a/src/xz/header.rs b/src/xz/header.rs index 0266414..b1c2802 100644 --- a/src/xz/header.rs +++ b/src/xz/header.rs @@ -2,9 +2,9 @@ use crate::decode::util; use crate::error; +use crate::xz::crc::CRC32; use crate::xz::StreamFlags; use byteorder::{BigEndian, LittleEndian, ReadBytesExt}; -use crc::crc32::{self, Hasher32}; /// File format magic header signature, see sect. 2.1.1.1. pub(crate) const XZ_MAGIC: &[u8] = &[0xFD, 0x37, 0x7A, 0x58, 0x5A, 0x00]; @@ -29,10 +29,10 @@ impl StreamHeader { } let (flags, digested) = { - let mut digest = crc32::Digest::new(crc32::IEEE); - let mut digest_rd = util::HasherRead::new(input, &mut digest); - let value = digest_rd.read_u16::()?; - (value, digest.sum32()) + let mut digest = CRC32.digest(); + let mut digest_rd = util::CrcDigestRead::new(input, &mut digest); + let flags = digest_rd.read_u16::()?; + (flags, digest.finalize()) }; let crc32 = input.read_u32::()?; diff --git a/src/xz/mod.rs b/src/xz/mod.rs index d68ed6c..aae2dd1 100644 --- a/src/xz/mod.rs +++ b/src/xz/mod.rs @@ -7,6 +7,7 @@ use crate::error; use std::io; +pub(crate) mod crc; pub(crate) mod footer; pub(crate) mod header;