fix: Prevent panic when trying to read a file with an unsupported compression method
This commit is contained in:
parent
7f46b77da2
commit
f7ab2ae506
1 changed files with 38 additions and 16 deletions
54
src/read.rs
54
src/read.rs
|
@ -82,7 +82,7 @@ pub(crate) mod zip_archive {
|
||||||
|
|
||||||
#[cfg(feature = "lzma")]
|
#[cfg(feature = "lzma")]
|
||||||
use crate::read::lzma::LzmaDecoder;
|
use crate::read::lzma::LzmaDecoder;
|
||||||
use crate::result::ZipError::InvalidPassword;
|
use crate::result::ZipError::{InvalidPassword, UnsupportedArchive};
|
||||||
use crate::spec::path_to_string;
|
use crate::spec::path_to_string;
|
||||||
use crate::unstable::LittleEndianReadExt;
|
use crate::unstable::LittleEndianReadExt;
|
||||||
pub use zip_archive::ZipArchive;
|
pub use zip_archive::ZipArchive;
|
||||||
|
@ -283,39 +283,61 @@ pub(crate) fn make_reader(
|
||||||
compression_method: CompressionMethod,
|
compression_method: CompressionMethod,
|
||||||
crc32: u32,
|
crc32: u32,
|
||||||
reader: CryptoReader,
|
reader: CryptoReader,
|
||||||
) -> ZipFileReader {
|
) -> ZipResult<ZipFileReader> {
|
||||||
let ae2_encrypted = reader.is_ae2_encrypted();
|
let ae2_encrypted = reader.is_ae2_encrypted();
|
||||||
|
|
||||||
match compression_method {
|
match compression_method {
|
||||||
CompressionMethod::Stored => {
|
CompressionMethod::Stored => Ok(ZipFileReader::Stored(Crc32Reader::new(
|
||||||
ZipFileReader::Stored(Crc32Reader::new(reader, crc32, ae2_encrypted))
|
reader,
|
||||||
}
|
crc32,
|
||||||
|
ae2_encrypted,
|
||||||
|
))),
|
||||||
#[cfg(feature = "_deflate-any")]
|
#[cfg(feature = "_deflate-any")]
|
||||||
CompressionMethod::Deflated => {
|
CompressionMethod::Deflated => {
|
||||||
let deflate_reader = DeflateDecoder::new(reader);
|
let deflate_reader = DeflateDecoder::new(reader);
|
||||||
ZipFileReader::Deflated(Crc32Reader::new(deflate_reader, crc32, ae2_encrypted))
|
Ok(ZipFileReader::Deflated(Crc32Reader::new(
|
||||||
|
deflate_reader,
|
||||||
|
crc32,
|
||||||
|
ae2_encrypted,
|
||||||
|
)))
|
||||||
}
|
}
|
||||||
#[cfg(feature = "deflate64")]
|
#[cfg(feature = "deflate64")]
|
||||||
CompressionMethod::Deflate64 => {
|
CompressionMethod::Deflate64 => {
|
||||||
let deflate64_reader = Deflate64Decoder::new(reader);
|
let deflate64_reader = Deflate64Decoder::new(reader);
|
||||||
ZipFileReader::Deflate64(Crc32Reader::new(deflate64_reader, crc32, ae2_encrypted))
|
Ok(ZipFileReader::Deflate64(Crc32Reader::new(
|
||||||
|
deflate64_reader,
|
||||||
|
crc32,
|
||||||
|
ae2_encrypted,
|
||||||
|
)))
|
||||||
}
|
}
|
||||||
#[cfg(feature = "bzip2")]
|
#[cfg(feature = "bzip2")]
|
||||||
CompressionMethod::Bzip2 => {
|
CompressionMethod::Bzip2 => {
|
||||||
let bzip2_reader = BzDecoder::new(reader);
|
let bzip2_reader = BzDecoder::new(reader);
|
||||||
ZipFileReader::Bzip2(Crc32Reader::new(bzip2_reader, crc32, ae2_encrypted))
|
Ok(ZipFileReader::Bzip2(Crc32Reader::new(
|
||||||
|
bzip2_reader,
|
||||||
|
crc32,
|
||||||
|
ae2_encrypted,
|
||||||
|
)))
|
||||||
}
|
}
|
||||||
#[cfg(feature = "zstd")]
|
#[cfg(feature = "zstd")]
|
||||||
CompressionMethod::Zstd => {
|
CompressionMethod::Zstd => {
|
||||||
let zstd_reader = ZstdDecoder::new(reader).unwrap();
|
let zstd_reader = ZstdDecoder::new(reader).unwrap();
|
||||||
ZipFileReader::Zstd(Crc32Reader::new(zstd_reader, crc32, ae2_encrypted))
|
Ok(ZipFileReader::Zstd(Crc32Reader::new(
|
||||||
|
zstd_reader,
|
||||||
|
crc32,
|
||||||
|
ae2_encrypted,
|
||||||
|
)))
|
||||||
}
|
}
|
||||||
#[cfg(feature = "lzma")]
|
#[cfg(feature = "lzma")]
|
||||||
CompressionMethod::Lzma => {
|
CompressionMethod::Lzma => {
|
||||||
let reader = LzmaDecoder::new(reader);
|
let reader = LzmaDecoder::new(reader);
|
||||||
ZipFileReader::Lzma(Crc32Reader::new(Box::new(reader), crc32, ae2_encrypted))
|
Ok(ZipFileReader::Lzma(Crc32Reader::new(
|
||||||
|
Box::new(reader),
|
||||||
|
crc32,
|
||||||
|
ae2_encrypted,
|
||||||
|
)))
|
||||||
}
|
}
|
||||||
_ => panic!("Compression method not supported"),
|
_ => Err(UnsupportedArchive("Compression method not supported")),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1042,13 +1064,13 @@ fn parse_extra_field(file: &mut ZipFileData) -> ZipResult<()> {
|
||||||
|
|
||||||
/// Methods for retrieving information on zip files
|
/// Methods for retrieving information on zip files
|
||||||
impl<'a> ZipFile<'a> {
|
impl<'a> ZipFile<'a> {
|
||||||
fn get_reader(&mut self) -> &mut ZipFileReader<'a> {
|
fn get_reader(&mut self) -> ZipResult<&mut ZipFileReader<'a>> {
|
||||||
if let ZipFileReader::NoReader = self.reader {
|
if let ZipFileReader::NoReader = self.reader {
|
||||||
let data = &self.data;
|
let data = &self.data;
|
||||||
let crypto_reader = self.crypto_reader.take().expect("Invalid reader state");
|
let crypto_reader = self.crypto_reader.take().expect("Invalid reader state");
|
||||||
self.reader = make_reader(data.compression_method, data.crc32, crypto_reader)
|
self.reader = make_reader(data.compression_method, data.crc32, crypto_reader)?;
|
||||||
}
|
}
|
||||||
&mut self.reader
|
Ok(&mut self.reader)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn get_raw_reader(&mut self) -> &mut dyn Read {
|
pub(crate) fn get_raw_reader(&mut self) -> &mut dyn Read {
|
||||||
|
@ -1205,7 +1227,7 @@ impl<'a> ZipFile<'a> {
|
||||||
|
|
||||||
impl<'a> Read for ZipFile<'a> {
|
impl<'a> Read for ZipFile<'a> {
|
||||||
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
|
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
|
||||||
self.get_reader().read(buf)
|
self.get_reader()?.read(buf)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1345,7 +1367,7 @@ pub fn read_zipfile_from_stream<'a, R: Read>(reader: &'a mut R) -> ZipResult<Opt
|
||||||
Ok(Some(ZipFile {
|
Ok(Some(ZipFile {
|
||||||
data: Cow::Owned(result),
|
data: Cow::Owned(result),
|
||||||
crypto_reader: None,
|
crypto_reader: None,
|
||||||
reader: make_reader(result_compression_method, result_crc32, crypto_reader),
|
reader: make_reader(result_compression_method, result_crc32, crypto_reader)?,
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue