Skip to content
This repository has been archived by the owner on Jun 2, 2024. It is now read-only.

Commit

Permalink
Improve several Read methods on ZipFile
Browse files Browse the repository at this point in the history
  • Loading branch information
a1phyr committed Apr 5, 2024
1 parent 3e88fe6 commit 82177e9
Show file tree
Hide file tree
Showing 2 changed files with 116 additions and 3 deletions.
35 changes: 32 additions & 3 deletions src/crc32.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,20 +36,49 @@ impl<R> Crc32Reader<R> {
}
}

#[cold]
fn invalid_checksum() -> io::Error {
io::Error::new(io::ErrorKind::InvalidData, "Invalid checksum")
}

impl<R: Read> Read for Crc32Reader<R> {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
let invalid_check = !buf.is_empty() && !self.check_matches() && !self.ae2_encrypted;

let count = match self.inner.read(buf) {
Ok(0) if invalid_check => {
return Err(io::Error::new(io::ErrorKind::Other, "Invalid checksum"))
}
Ok(0) if invalid_check => return Err(invalid_checksum()),
Ok(n) => n,
Err(e) => return Err(e),
};
self.hasher.update(&buf[0..count]);
Ok(count)
}

fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
let start = buf.len();
let n = self.inner.read_to_end(buf)?;

self.hasher.update(&buf[start..]);

if !self.check_matches() && !self.ae2_encrypted {
return Err(invalid_checksum());
}

Ok(n)
}

fn read_to_string(&mut self, buf: &mut String) -> io::Result<usize> {
let start = buf.len();
let n = self.inner.read_to_string(buf)?;

self.hasher.update(&buf.as_bytes()[start..]);

if !self.check_matches() && !self.ae2_encrypted {
return Err(invalid_checksum());
}

Ok(n)
}
}

#[cfg(test)]
Expand Down
84 changes: 84 additions & 0 deletions src/read.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,24 @@ impl<'a> Read for CryptoReader<'a> {
CryptoReader::Aes { reader: r, .. } => r.read(buf),
}
}

fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
match self {
CryptoReader::Plaintext(r) => r.read_to_end(buf),
CryptoReader::ZipCrypto(r) => r.read_to_end(buf),
#[cfg(feature = "aes-crypto")]
CryptoReader::Aes { reader: r, .. } => r.read_to_end(buf),
}
}

fn read_to_string(&mut self, buf: &mut String) -> io::Result<usize> {
match self {
CryptoReader::Plaintext(r) => r.read_to_string(buf),
CryptoReader::ZipCrypto(r) => r.read_to_string(buf),
#[cfg(feature = "aes-crypto")]
CryptoReader::Aes { reader: r, .. } => r.read_to_string(buf),
}
}
}

impl<'a> CryptoReader<'a> {
Expand Down Expand Up @@ -153,6 +171,60 @@ impl<'a> Read for ZipFileReader<'a> {
ZipFileReader::Zstd(r) => r.read(buf),
}
}

fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> {
match self {
ZipFileReader::NoReader => panic!("ZipFileReader was in an invalid state"),
ZipFileReader::Raw(r) => r.read_exact(buf),
ZipFileReader::Stored(r) => r.read_exact(buf),
#[cfg(any(
feature = "deflate",
feature = "deflate-miniz",
feature = "deflate-zlib"
))]
ZipFileReader::Deflated(r) => r.read_exact(buf),
#[cfg(feature = "bzip2")]
ZipFileReader::Bzip2(r) => r.read_exact(buf),
#[cfg(feature = "zstd")]
ZipFileReader::Zstd(r) => r.read_exact(buf),
}
}

fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
match self {
ZipFileReader::NoReader => panic!("ZipFileReader was in an invalid state"),
ZipFileReader::Raw(r) => r.read_to_end(buf),
ZipFileReader::Stored(r) => r.read_to_end(buf),
#[cfg(any(
feature = "deflate",
feature = "deflate-miniz",
feature = "deflate-zlib"
))]
ZipFileReader::Deflated(r) => r.read_to_end(buf),
#[cfg(feature = "bzip2")]
ZipFileReader::Bzip2(r) => r.read_to_end(buf),
#[cfg(feature = "zstd")]
ZipFileReader::Zstd(r) => r.read_to_end(buf),
}
}

fn read_to_string(&mut self, buf: &mut String) -> io::Result<usize> {
match self {
ZipFileReader::NoReader => panic!("ZipFileReader was in an invalid state"),
ZipFileReader::Raw(r) => r.read_to_string(buf),
ZipFileReader::Stored(r) => r.read_to_string(buf),
#[cfg(any(
feature = "deflate",
feature = "deflate-miniz",
feature = "deflate-zlib"
))]
ZipFileReader::Deflated(r) => r.read_to_string(buf),
#[cfg(feature = "bzip2")]
ZipFileReader::Bzip2(r) => r.read_to_string(buf),
#[cfg(feature = "zstd")]
ZipFileReader::Zstd(r) => r.read_to_string(buf),
}
}
}

impl<'a> ZipFileReader<'a> {
Expand Down Expand Up @@ -979,6 +1051,18 @@ impl<'a> Read for ZipFile<'a> {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
self.get_reader().read(buf)
}

fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> {
self.get_reader().read_exact(buf)
}

fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
self.get_reader().read_to_end(buf)
}

fn read_to_string(&mut self, buf: &mut String) -> io::Result<usize> {
self.get_reader().read_to_string(buf)
}
}

impl<'a> Drop for ZipFile<'a> {
Expand Down

0 comments on commit 82177e9

Please sign in to comment.