Skip to content

Commit

Permalink
Merge pull request #78 from SnowflakePowered/patch-update-crc
Browse files Browse the repository at this point in the history
Update dependencies (particularly crc 3.0.0)
  • Loading branch information
gendx committed Aug 26, 2022
2 parents 4ab5883 + 698620b commit c80e4aa
Show file tree
Hide file tree
Showing 8 changed files with 67 additions and 70 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
23 changes: 11 additions & 12 deletions src/decode/util.rs
@@ -1,4 +1,4 @@
use std::{hash, io};
use std::io;

pub fn read_tag<R: io::BufRead>(input: &mut R, tag: &[u8]) -> io::Result<bool> {
let mut buf = vec![0; tag.len()];
Expand Down Expand Up @@ -34,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
24 changes: 11 additions & 13 deletions 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<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
28 changes: 14 additions & 14 deletions 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;

Expand Down Expand Up @@ -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::<LittleEndian>(crc32)?;
Ok(())
}
Expand All @@ -47,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 @@ -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
Expand All @@ -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::<LittleEndian>(crc32)?;

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

Ok(count_output.count())
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);
10 changes: 5 additions & 5 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 @@ -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::<BigEndian>()?;
(value, digest.sum32())
let mut digest = CRC32.digest();
let mut digest_rd = util::CrcDigestRead::new(input, &mut digest);
let flags = digest_rd.read_u16::<BigEndian>()?;
(flags, digest.finalize())
};

let crc32 = input.read_u32::<LittleEndian>()?;
Expand Down
1 change: 1 addition & 0 deletions src/xz/mod.rs
Expand Up @@ -7,6 +7,7 @@
use crate::error;
use std::io;

pub(crate) mod crc;
pub(crate) mod footer;
pub(crate) mod header;

Expand Down

0 comments on commit c80e4aa

Please sign in to comment.