Skip to content

Commit

Permalink
GZ: add support for checksumming the header
Browse files Browse the repository at this point in the history
  • Loading branch information
Diggory Hardy committed Dec 1, 2014
1 parent bb4d4c4 commit 7e02580
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 17 deletions.
6 changes: 3 additions & 3 deletions src/crc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,10 @@ impl Crc {
pub fn sum(&self) -> libc::c_ulong { self.crc }
pub fn amt(&self) -> u32 { self.amt }

pub fn update(&mut self, with: &[u8]) {
self.amt += with.len() as u32;
pub fn update(&mut self, data: &[u8]) {
self.amt += data.len() as u32;
self.crc = unsafe {
ffi::mz_crc32(self.crc, with.as_ptr(), with.len() as libc::size_t)
ffi::mz_crc32(self.crc, data.as_ptr(), data.len() as libc::size_t)
};
}
}
Expand Down
34 changes: 20 additions & 14 deletions src/gz.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use std::io::{BytesReader,IoResult, IoError};
use std::io;
use std::os;
use std::slice::bytes;
use libc;

use {BestCompression, CompressionLevel, BestSpeed};
use crc::{CrcReader, Crc};
Expand Down Expand Up @@ -308,28 +309,31 @@ impl<R: Reader> DecoderReader<R> {
///
/// If an error is encountered when parsing the gzip header, an error is
/// returned.
pub fn new(mut r: R) -> IoResult<DecoderReader<R>> {
let id1 = try!(r.read_u8());
let id2 = try!(r.read_u8());
pub fn new(r: R) -> IoResult<DecoderReader<R>> {
// from here, all reads should go through this reader (not r):
let mut crc_reader = CrcReader::new( r );

let id1 = try!(crc_reader.read_u8());
let id2 = try!(crc_reader.read_u8());
if id1 != 0x1f || id2 != 0x8b { return Err(bad_header()) }
let cm = try!(r.read_u8());
let cm = try!(crc_reader.read_u8());
if cm != 8 { return Err(bad_header()) }

let flg = try!(r.read_u8());
let mtime = try!(r.read_le_u32());
let _xfl = try!(r.read_u8());
let _os = try!(r.read_u8());
let flg = try!(crc_reader.read_u8());
let mtime = try!(crc_reader.read_le_u32());
let _xfl = try!(crc_reader.read_u8());
let _os = try!(crc_reader.read_u8());

let extra = if flg & FEXTRA != 0 {
let xlen = try!(r.read_le_u16());
Some(try!(r.read_exact(xlen as uint)))
let xlen = try!(crc_reader.read_le_u16());
Some(try!(crc_reader.read_exact(xlen as uint)))
} else {
None
};
let filename = if flg & FNAME != 0 {
// wow this is slow
let mut b = Vec::new();
for byte in r.bytes() {
for byte in crc_reader.bytes() {
let byte = try!(byte);
if byte == 0 { break }
b.push(byte);
Expand All @@ -341,7 +345,7 @@ impl<R: Reader> DecoderReader<R> {
let comment = if flg & FCOMMENT != 0 {
// wow this is slow
let mut b = Vec::new();
for byte in r.bytes() {
for byte in crc_reader.bytes() {
let byte = try!(byte);
if byte == 0 { break }
b.push(byte);
Expand All @@ -352,10 +356,12 @@ impl<R: Reader> DecoderReader<R> {
};

if flg & FHCRC != 0 {
try!(r.read_le_u16());
let calced_crc = crc_reader.crc().sum() & 0xFFFF;
let stored_crc = try!(crc_reader.read_le_u16()) as libc::c_ulong;
if calced_crc != stored_crc { return Err(corrupt()) }
}

let flate = raw::DecoderReader::new(r, true, Vec::with_capacity(128 * 1024));
let flate = raw::DecoderReader::new(crc_reader.unwrap(), true, Vec::with_capacity(128 * 1024));
return Ok(DecoderReader {
inner: CrcReader::new(flate),
header: Header {
Expand Down

0 comments on commit 7e02580

Please sign in to comment.