Skip to content

Commit

Permalink
Update dependencies and adapt to crc v3 API
Browse files Browse the repository at this point in the history
  • Loading branch information
chyyran committed Aug 24, 2022
1 parent a24679d commit e51f885
Show file tree
Hide file tree
Showing 11 changed files with 71 additions and 81 deletions.
8 changes: 4 additions & 4 deletions Cargo.toml
Expand Up @@ -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"
Expand Down
3 changes: 1 addition & 2 deletions src/decode/lzma.rs
@@ -1,8 +1,7 @@
use crate::decode::lzbuffer::{LzBuffer, LzCircularBuffer};
use crate::decode::rangecoder;
use crate::decode::rangecoder::RangeDecoder;
use crate::decompress::Options;
use crate::decompress::UnpackedSize;
use crate::decompress::{Options, UnpackedSize};
use crate::error;
use byteorder::{LittleEndian, ReadBytesExt};
use std::io;
Expand Down
6 changes: 2 additions & 4 deletions src/decode/lzma2.rs
@@ -1,8 +1,6 @@
use crate::decode::lzbuffer;
use crate::decode::lzbuffer::LzBuffer;
use crate::decode::lzma::DecoderState;
use crate::decode::lzma::LzmaProperties;
use crate::decode::rangecoder;
use crate::decode::lzma::{DecoderState, LzmaProperties};
use crate::decode::{lzbuffer, rangecoder};
use crate::error;
use byteorder::{BigEndian, ReadBytesExt};
use std::io;
Expand Down
22 changes: 10 additions & 12 deletions src/decode/util.rs
@@ -1,4 +1,3 @@
use std::hash;
use std::io;

pub fn read_tag<R: io::BufRead>(input: &mut R, tag: &[u8]) -> io::Result<bool> {
Expand Down Expand Up @@ -35,33 +34,32 @@ pub fn flush_zero_padding<R: io::BufRead>(input: &mut R) -> io::Result<bool> {
}

// 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<usize> {
let result = self.read.read(buf)?;
self.hasher.write(&buf[..result]);
self.digest.update(&buf[..result]);
Ok(result)
}
}
Expand Down
39 changes: 17 additions & 22 deletions src/decode/xz.rs
Expand Up @@ -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;

Expand Down Expand Up @@ -46,11 +45,9 @@ where
};

let crc32 = input.read_u32::<LittleEndian>()?;
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::<LittleEndian>()?;
if index_size as u32 != (backward_size + 1) << 2 {
return Err(error::Error::XzError(format!(
Expand All @@ -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}",
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -138,8 +134,7 @@ where
)));
}
}
}

};
// TODO: create padding parser function
let count = count_input.count();
let padding_size = ((count ^ 0x03) + 1) & 0x03;
Expand All @@ -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 {
Expand All @@ -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::<LittleEndian>()?;
Expand Down Expand Up @@ -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::<LittleEndian>()?;
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}",
Expand Down Expand Up @@ -309,7 +304,7 @@ where
CheckMethod::None => (),
CheckMethod::Crc32 => {
let crc32 = input.read_u32::<LittleEndian>()?;
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}",
Expand All @@ -319,7 +314,7 @@ where
}
CheckMethod::Crc64 => {
let crc64 = input.read_u64::<LittleEndian>()?;
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}",
Expand Down
23 changes: 10 additions & 13 deletions src/encode/util.rs
@@ -1,37 +1,34 @@
use std::hash;
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<usize> {
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()
}
Expand Down
31 changes: 15 additions & 16 deletions src/encode/xz.rs
@@ -1,9 +1,8 @@
use crate::decode;
use crate::encode::lzma2;
use crate::encode::util;
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;

Expand Down Expand Up @@ -34,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::<LittleEndian>(crc32)?;
Ok(())
}
Expand All @@ -48,16 +47,16 @@ fn write_footer<W>(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<u8> = 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::<LittleEndian>(backward_size as u32)?;
stream_flags.serialize(&mut digested)?;
}
let crc32 = digest.sum32();
let crc32 = digest.finalize();
output.write_u32::<LittleEndian>(crc32)?;
output.write_all(footer_buf.as_slice())?;

Expand All @@ -74,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
Expand All @@ -90,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::<LittleEndian>(crc32)?;

// Block
Expand Down Expand Up @@ -118,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)?;
Expand All @@ -133,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::<LittleEndian>(crc32)?;

Ok(count_output.count())
Expand Down
3 changes: 1 addition & 2 deletions src/error.rs
@@ -1,8 +1,7 @@
//! Error handling.

use std::fmt::Display;
use std::io;
use std::result;
use std::{io, result};

/// Library errors.
#[derive(Debug)]
Expand Down
4 changes: 4 additions & 0 deletions src/xz/crc.rs
@@ -0,0 +1,4 @@
use crc::{Crc, CRC_32_ISO_HDLC, CRC_64_XZ};

pub const CRC32: Crc<u32> = Crc::<u32>::new(&CRC_32_ISO_HDLC);
pub const CRC64: Crc<u64> = Crc::<u64>::new(&CRC_64_XZ);
12 changes: 6 additions & 6 deletions src/xz/header.rs
Expand Up @@ -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];
Expand All @@ -28,13 +28,13 @@ 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::<BigEndian>()?;
(value, digest.sum32())
let mut digest = CRC32.digest();
let flags = {
let mut digest_rd = util::CrcDigestRead::new(input, &mut digest);
digest_rd.read_u16::<BigEndian>()?
};

let digested = digest.finalize();
let crc32 = input.read_u32::<LittleEndian>()?;
if crc32 != digested {
return Err(error::Error::XzError(format!(
Expand Down

0 comments on commit e51f885

Please sign in to comment.