Skip to content

Commit

Permalink
fix: Decrypt the read bytes in ZipCrypto instead of entire buffer
Browse files Browse the repository at this point in the history
Fixes `corrupt deflate stream` panic when extracting a file from encrypted archive (zip-rs/zip-old#280).
  • Loading branch information
awaken1ng committed Apr 27, 2024
1 parent b718fdf commit 4078bd3
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 3 deletions.
6 changes: 3 additions & 3 deletions src/zipcrypto.rs
Original file line number Diff line number Diff line change
Expand Up @@ -183,11 +183,11 @@ impl<R: std::io::Read> std::io::Read for ZipCryptoReaderValid<R> {
// Note: There might be potential for optimization. Inspiration can be found at:
// https://github.com/kornelski/7z/blob/master/CPP/7zip/Crypto/ZipCrypto.cpp

let result = self.reader.file.read(buf);
for byte in buf.iter_mut() {
let n = self.reader.file.read(buf)?;
for byte in buf.iter_mut().take(n) {
*byte = self.reader.keys.decrypt_byte(*byte);
}
result
Ok(n)
}
}

Expand Down
18 changes: 18 additions & 0 deletions tests/zip_crypto.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,3 +102,21 @@ fn encrypted_file() {
assert_eq!(data, "abcdefghijklmnopqrstuvwxyz123456789".as_bytes());
}
}

#[test]
fn buffered_read() {
use std::io::{BufReader, Read};

// delibirately pick a buffer capacity in a way that when `ZipCryptoReaderValid` read happens, it's not going to take entire buffer,
// for this file it needs to be between 13..=46 bytes (with exception of 44 bytes)
let zip_file_bytes = &mut Cursor::new(ZIP_CRYPTO_FILE);
let buffered = BufReader::with_capacity(13, zip_file_bytes);
let mut archive = zip::ZipArchive::new(buffered).unwrap();

let mut file = archive.by_index_decrypt(0, b"test").unwrap();

// should not panic with `Custom { kind: Other, error: "Invalid checksum" }`
// or `Custom { kind: InvalidInput, error: "corrupt deflate stream" }`
let mut data = Vec::new();
file.read_to_end(&mut data).unwrap();
}

0 comments on commit 4078bd3

Please sign in to comment.