aboutsummaryrefslogtreecommitdiff
path: root/src/zip/file
diff options
context:
space:
mode:
Diffstat (limited to 'src/zip/file')
-rw-r--r--src/zip/file/info.rs8
-rw-r--r--src/zip/file/read.rs42
-rw-r--r--src/zip/file/write.rs4
3 files changed, 39 insertions, 15 deletions
diff --git a/src/zip/file/info.rs b/src/zip/file/info.rs
index 2891b59..ff6e8d2 100644
--- a/src/zip/file/info.rs
+++ b/src/zip/file/info.rs
@@ -7,8 +7,8 @@ pub enum CompressionMethod {
7 Store, 7 Store,
8 Deflate, 8 Deflate,
9 BZip2, 9 BZip2,
10 LZMA, 10 Lzma,
11 XZ, 11 Xz,
12} 12}
13 13
14impl CompressionMethod { 14impl CompressionMethod {
@@ -17,8 +17,8 @@ impl CompressionMethod {
17 0 => Ok(Self::Store), 17 0 => Ok(Self::Store),
18 8 => Ok(Self::Deflate), 18 8 => Ok(Self::Deflate),
19 12 => Ok(Self::BZip2), 19 12 => Ok(Self::BZip2),
20 14 => Ok(Self::LZMA), 20 14 => Ok(Self::Lzma),
21 95 => Ok(Self::XZ), 21 95 => Ok(Self::Xz),
22 1..=7 | 9..=11 | 13 | 15..=20 | 93..=94 | 96..=99 => { 22 1..=7 | 9..=11 | 13 | 15..=20 | 93..=94 | 96..=99 => {
23 Err(ZipError::UnsupportedCompressionMethod.into()) 23 Err(ZipError::UnsupportedCompressionMethod.into())
24 } 24 }
diff --git a/src/zip/file/read.rs b/src/zip/file/read.rs
index 56f42da..c5c7e99 100644
--- a/src/zip/file/read.rs
+++ b/src/zip/file/read.rs
@@ -2,16 +2,17 @@ use crate::driver::FileDriver;
2use crate::zip::{CompressionMethod, ZipError, ZipFileInfo, ZipResult}; 2use crate::zip::{CompressionMethod, ZipError, ZipFileInfo, ZipResult};
3use bzip2::read::BzDecoder; 3use bzip2::read::BzDecoder;
4use flate2::read::DeflateDecoder; 4use flate2::read::DeflateDecoder;
5use liblzma::read::XzDecoder;
6use liblzma::stream::{Filters, LzmaOptions, Stream};
5use std::io::{ 7use std::io::{
6 Error as IoError, ErrorKind as IoErrorKind, Read, Result as IoResult, Seek, SeekFrom, 8 Error as IoError, ErrorKind as IoErrorKind, Read, Result as IoResult, Seek, SeekFrom,
7}; 9};
8use xz2::read::XzDecoder;
9 10
10enum IoProxy<Io: Read> { 11enum IoProxy<Io: Read> {
11 Store(Io), 12 Store(Io),
12 Deflate(DeflateDecoder<Io>), 13 Deflate(DeflateDecoder<Io>),
13 BZip2(BzDecoder<Io>), 14 BZip2(BzDecoder<Io>),
14 XZ(XzDecoder<Io>), 15 Xz(XzDecoder<Io>),
15} 16}
16 17
17pub struct ZipFileReader<'d, Io: Read> { 18pub struct ZipFileReader<'d, Io: Read> {
@@ -39,6 +40,7 @@ impl<'d, Io: Read + Seek> ZipFileReader<'d, Io> {
39 io.read(&mut buf)?; 40 io.read(&mut buf)?;
40 buf 41 buf
41 }; 42 };
43
42 if u32::from_le_bytes(buf[..4].try_into().unwrap()) != 0x04034b50 { 44 if u32::from_le_bytes(buf[..4].try_into().unwrap()) != 0x04034b50 {
43 return Err(ZipError::InvalidFileHeaderSignature.into()); 45 return Err(ZipError::InvalidFileHeaderSignature.into());
44 } 46 }
@@ -46,20 +48,42 @@ impl<'d, Io: Read + Seek> ZipFileReader<'d, Io> {
46 + 30 48 + 30
47 + u16::from_le_bytes(buf[26..28].try_into().unwrap()) as u64 49 + u16::from_le_bytes(buf[26..28].try_into().unwrap()) as u64
48 + u16::from_le_bytes(buf[28..30].try_into().unwrap()) as u64; 50 + u16::from_le_bytes(buf[28..30].try_into().unwrap()) as u64;
49 io.seek(SeekFrom::Start(data_pointer))?; 51 let mut cursor = io.seek(SeekFrom::Start(data_pointer))?;
50 52
51 Ok(Self { 53 Ok(Self {
52 io: match info.compression_method { 54 io: match info.compression_method {
53 CompressionMethod::Store => IoProxy::Store(io), 55 CompressionMethod::Store => IoProxy::Store(io),
54 CompressionMethod::Deflate => IoProxy::Deflate(DeflateDecoder::new(io)), 56 CompressionMethod::Deflate => IoProxy::Deflate(DeflateDecoder::new(io)),
55 CompressionMethod::BZip2 => IoProxy::BZip2(BzDecoder::new(io)), 57 CompressionMethod::BZip2 => IoProxy::BZip2(BzDecoder::new(io)),
56 CompressionMethod::LZMA => IoProxy::XZ(XzDecoder::new(io)), 58 CompressionMethod::Lzma => {
57 CompressionMethod::XZ => IoProxy::XZ(XzDecoder::new(io)), 59 let buf = {
60 let mut buf = [0; 9];
61 io.read(&mut buf)?;
62 cursor += 9;
63 buf
64 };
65 IoProxy::Xz(XzDecoder::new_stream(
66 io,
67 Stream::new_raw_decoder(
68 Filters::new().lzma1(
69 LzmaOptions::new()
70 .literal_context_bits((buf[4] % 9) as u32)
71 .literal_position_bits((buf[4] / 9 % 5) as u32)
72 .position_bits((buf[4] / 45) as u32)
73 .dict_size(
74 u32::from_le_bytes(buf[5..9].try_into().unwrap()).min(4096),
75 ),
76 ),
77 )
78 .unwrap(),
79 ))
80 }
81 CompressionMethod::Xz => IoProxy::Xz(XzDecoder::new(io)),
58 }, 82 },
59 info, 83 info,
60 84
61 bounds: (data_pointer, data_pointer + info.compressed_size), 85 bounds: (cursor, data_pointer + info.compressed_size),
62 cursor: data_pointer, 86 cursor: cursor,
63 }) 87 })
64 } 88 }
65 89
@@ -78,7 +102,7 @@ impl<'d, Io: Read> Read for ZipFileReader<'d, Io> {
78 IoProxy::Store(io) => io.read(&mut buf[..upper]), 102 IoProxy::Store(io) => io.read(&mut buf[..upper]),
79 IoProxy::Deflate(io) => io.read(&mut buf[..upper]), 103 IoProxy::Deflate(io) => io.read(&mut buf[..upper]),
80 IoProxy::BZip2(io) => io.read(&mut buf[..upper]), 104 IoProxy::BZip2(io) => io.read(&mut buf[..upper]),
81 IoProxy::XZ(io) => io.read(&mut buf[..upper]), 105 IoProxy::Xz(io) => io.read(&mut buf[..upper]),
82 }?; 106 }?;
83 self.cursor += upper as u64; 107 self.cursor += upper as u64;
84 Ok(bytes) 108 Ok(bytes)
@@ -118,7 +142,7 @@ impl<'d, Io: Read + Seek> Seek for ZipFileReader<'d, Io> {
118 } 142 }
119 _ => Err(IoError::new( 143 _ => Err(IoError::new(
120 IoErrorKind::Unsupported, 144 IoErrorKind::Unsupported,
121 ZipError::CompressionDataIsUnseekable, 145 ZipError::CompressedDataIsUnseekable,
122 )), 146 )),
123 } 147 }
124 } 148 }
diff --git a/src/zip/file/write.rs b/src/zip/file/write.rs
index 627db6d..6f5756a 100644
--- a/src/zip/file/write.rs
+++ b/src/zip/file/write.rs
@@ -2,14 +2,14 @@ use crate::driver::FileDriver;
2use crate::zip::ZipFileInfo; 2use crate::zip::ZipFileInfo;
3use bzip2::write::BzEncoder; 3use bzip2::write::BzEncoder;
4use flate2::write::DeflateEncoder; 4use flate2::write::DeflateEncoder;
5use liblzma::write::XzEncoder;
5use std::io::Write; 6use std::io::Write;
6use xz2::write::XzEncoder;
7 7
8enum IoProxy<Io: Write> { 8enum IoProxy<Io: Write> {
9 Store(Io), 9 Store(Io),
10 Deflate(DeflateEncoder<Io>), 10 Deflate(DeflateEncoder<Io>),
11 BZip2(BzEncoder<Io>), 11 BZip2(BzEncoder<Io>),
12 XZ(XzEncoder<Io>), 12 Xz(XzEncoder<Io>),
13} 13}
14 14
15pub struct ZipFileWriter<'d, Io: Write> { 15pub struct ZipFileWriter<'d, Io: Write> {