refactor: Eliminate some magic numbers and unnecessary path prefixes (#225)

* refactor: eliminate a magic number for CDE block size

* refactor: Minor refactors

* refactor: Can use cde_start_pos to locate ZIP64 end locator

* chore: Fix import that can no longer be feature-gated

* chore: Fix import that can no longer be feature-gated
This commit is contained in:
Chris Hennick 2024-07-27 18:43:44 -07:00 committed by GitHub
parent a29b860395
commit 3ecd65176c
Signed by: DevComp
GPG key ID: B5690EEEBB952194
2 changed files with 97 additions and 115 deletions

View file

@ -8,7 +8,10 @@ use crate::crc32::Crc32Reader;
use crate::extra_fields::{ExtendedTimestamp, ExtraField};
use crate::read::zip_archive::{Shared, SharedBuilder};
use crate::result::{ZipError, ZipResult};
use crate::spec::{self, FixedSizeBlock, Pod, Zip32CentralDirectoryEnd, ZIP64_ENTRY_THR};
use crate::spec::{
self, FixedSizeBlock, Pod, Zip32CentralDirectoryEnd, Zip64CDELocatorBlock,
Zip64CentralDirectoryEnd, ZIP64_ENTRY_THR,
};
use crate::types::{
AesMode, AesVendorVersion, DateTime, System, ZipCentralEntryBlock, ZipFileData,
ZipLocalEntryBlock,
@ -47,7 +50,7 @@ pub(crate) mod zip_archive {
/// Extract immutable data from `ZipArchive` to make it cheap to clone
#[derive(Debug)]
pub(crate) struct Shared {
pub(crate) files: super::IndexMap<Box<str>, super::ZipFileData>,
pub(crate) files: IndexMap<Box<str>, super::ZipFileData>,
pub(super) offset: u64,
pub(super) dir_start: u64,
// This isn't yet used anywhere, but it is here for use cases in the future.
@ -324,7 +327,7 @@ pub(crate) fn find_content<'a>(
None => find_data_start(data, reader)?,
};
reader.seek(io::SeekFrom::Start(data_start))?;
reader.seek(SeekFrom::Start(data_start))?;
Ok((reader as &mut dyn Read).take(data.compressed_size))
}
@ -334,7 +337,7 @@ fn find_content_seek<'a, R: Read + Seek>(
) -> ZipResult<SeekableTake<'a, R>> {
// Parse local header
let data_start = find_data_start(data, reader)?;
reader.seek(io::SeekFrom::Start(data_start))?;
reader.seek(SeekFrom::Start(data_start))?;
// Explicit Ok and ? are needed to convert io::Error to ZipError
Ok(SeekableTake::new(reader, data.compressed_size)?)
@ -345,7 +348,7 @@ fn find_data_start(
reader: &mut (impl Read + Seek + Sized),
) -> Result<u64, ZipError> {
// Go to start of data.
reader.seek(io::SeekFrom::Start(data.header_start))?;
reader.seek(SeekFrom::Start(data.header_start))?;
// Parse static-sized fields and check the magic value.
let block = ZipLocalEntryBlock::parse(reader)?;
@ -449,7 +452,7 @@ impl<R> ZipArchive<R> {
Some((_, file)) => file.header_start,
None => central_start,
};
let shared = Arc::new(zip_archive::Shared {
let shared = Arc::new(Shared {
files,
offset: initial_offset,
dir_start: central_start,
@ -479,7 +482,7 @@ impl<R> ZipArchive<R> {
}
impl<R: Read + Seek> ZipArchive<R> {
pub(crate) fn merge_contents<W: Write + io::Seek>(
pub(crate) fn merge_contents<W: Write + Seek>(
&mut self,
mut w: W,
) -> ZipResult<IndexMap<Box<str>, ZipFileData>> {
@ -543,7 +546,7 @@ impl<R: Read + Seek> ZipArchive<R> {
fn get_directory_info_zip32(
config: &Config,
reader: &mut R,
footer: &spec::Zip32CentralDirectoryEnd,
footer: &Zip32CentralDirectoryEnd,
cde_start_pos: u64,
) -> ZipResult<CentralDirectoryInfo> {
let archive_offset = match config.archive_offset {
@ -556,15 +559,13 @@ impl<R: Read + Seek> ZipArchive<R> {
let mut offset = cde_start_pos
.checked_sub(footer.central_directory_size as u64)
.and_then(|x| x.checked_sub(footer.central_directory_offset as u64))
.ok_or(ZipError::InvalidArchive(
"Invalid central directory size or offset",
))?;
.ok_or(InvalidArchive("Invalid central directory size or offset"))?;
if config.archive_offset == ArchiveOffset::Detect {
// Check whether the archive offset makes sense by peeking at the directory start. If it
// doesn't, fall back to using no archive offset. This supports zips with the central
// directory entries somewhere other than directly preceding the end of central directory.
reader.seek(io::SeekFrom::Start(
reader.seek(SeekFrom::Start(
offset + footer.central_directory_offset as u64,
))?;
let mut buf = [0; 4];
@ -593,11 +594,6 @@ impl<R: Read + Seek> ZipArchive<R> {
})
}
const fn zip64_cde_len() -> usize {
mem::size_of::<spec::Zip64CentralDirectoryEnd>()
+ mem::size_of::<spec::Zip64CentralDirectoryEndLocator>()
}
const fn order_lower_upper_bounds(a: u64, b: u64) -> (u64, u64) {
if a > b {
(b, a)
@ -609,16 +605,18 @@ impl<R: Read + Seek> ZipArchive<R> {
fn get_directory_info_zip64(
config: &Config,
reader: &mut R,
footer: &spec::Zip32CentralDirectoryEnd,
cde_start_pos: u64,
) -> ZipResult<Vec<ZipResult<CentralDirectoryInfo>>> {
// See if there's a ZIP64 footer. The ZIP64 locator if present will
// have its signature 20 bytes in front of the standard footer. The
// standard footer, in turn, is 22+N bytes large, where N is the
// comment length. Therefore:
/* TODO: compute this from constant sizes and offsets! */
reader.seek(io::SeekFrom::End(
-(20 + 22 + footer.zip_file_comment.len() as i64),
reader.seek(SeekFrom::Start(
cde_start_pos
.checked_sub(size_of::<Zip64CDELocatorBlock>() as u64)
.ok_or(InvalidArchive(
"No room for ZIP64 locator before central directory end",
))?,
))?;
let locator64 = spec::Zip64CentralDirectoryEndLocator::parse(reader)?;
@ -632,8 +630,11 @@ impl<R: Read + Seek> ZipArchive<R> {
// ZIP comment data.
let search_upper_bound = cde_start_pos
.checked_sub(Self::zip64_cde_len() as u64)
.ok_or(ZipError::InvalidArchive(
.checked_sub(
(size_of::<Zip64CentralDirectoryEnd>()
+ size_of::<spec::Zip64CentralDirectoryEndLocator>()) as u64,
)
.ok_or(InvalidArchive(
"File cannot contain ZIP64 central directory end",
))?;
@ -642,7 +643,7 @@ impl<R: Read + Seek> ZipArchive<R> {
search_upper_bound,
);
let search_results = spec::Zip64CentralDirectoryEnd::find_and_parse(reader, lower, upper)?;
let search_results = Zip64CentralDirectoryEnd::find_and_parse(reader, lower, upper)?;
let results: Vec<ZipResult<CentralDirectoryInfo>> =
search_results.into_iter().map(|(footer64, archive_offset)| {
let archive_offset = match config.archive_offset {
@ -654,7 +655,7 @@ impl<R: Read + Seek> ZipArchive<R> {
// Check whether the archive offset makes sense by peeking at the directory start.
//
// If any errors occur or no header signature is found, fall back to no offset to see if that works.
reader.seek(io::SeekFrom::Start(start)).ok()?;
reader.seek(SeekFrom::Start(start)).ok()?;
let mut buf = [0; 4];
reader.read_exact(&mut buf).ok()?;
if spec::Magic::from_le_bytes(buf) != spec::Magic::CENTRAL_DIRECTORY_HEADER_SIGNATURE {
@ -669,19 +670,19 @@ impl<R: Read + Seek> ZipArchive<R> {
let directory_start = footer64
.central_directory_offset
.checked_add(archive_offset)
.ok_or(ZipError::InvalidArchive(
.ok_or(InvalidArchive(
"Invalid central directory size or offset",
))?;
if directory_start > search_upper_bound {
Err(ZipError::InvalidArchive(
Err(InvalidArchive(
"Invalid central directory size or offset",
))
} else if footer64.number_of_files_on_this_disk > footer64.number_of_files {
Err(ZipError::InvalidArchive(
Err(InvalidArchive(
"ZIP64 footer indicates more files on this disk than in the whole archive",
))
} else if footer64.version_needed_to_extract > footer64.version_made_by {
Err(ZipError::InvalidArchive(
Err(InvalidArchive(
"ZIP64 footer indicates a new version is needed to extract this archive than the \
version that wrote it",
))
@ -711,7 +712,7 @@ impl<R: Read + Seek> ZipArchive<R> {
let mut invalid_errors_64 = Vec::new();
let mut unsupported_errors_64 = Vec::new();
let mut ok_results = Vec::new();
let cde_locations = spec::Zip32CentralDirectoryEnd::find_and_parse(reader)?;
let cde_locations = Zip32CentralDirectoryEnd::find_and_parse(reader)?;
cde_locations
.into_vec()
.into_iter()
@ -728,7 +729,7 @@ impl<R: Read + Seek> ZipArchive<R> {
let mut inner_results = Vec::with_capacity(1);
// Check if file has a zip64 footer
let zip64_vec_result =
Self::get_directory_info_zip64(&config, reader, &footer, cde_start_pos);
Self::get_directory_info_zip64(&config, reader, cde_start_pos);
Self::sort_result(
zip64_vec_result,
&mut invalid_errors_64,
@ -798,7 +799,7 @@ impl<R: Read + Seek> ZipArchive<R> {
.next()
.unwrap());
};
reader.seek(io::SeekFrom::Start(shared.dir_start))?;
reader.seek(SeekFrom::Start(shared.dir_start))?;
Ok((Rc::try_unwrap(footer).unwrap(), shared.build()))
}
@ -818,7 +819,7 @@ impl<R: Read + Seek> ZipArchive<R> {
return unsupported_zip_error("Support for multi-disk files is not implemented");
}
let mut files = Vec::with_capacity(file_capacity);
reader.seek(io::SeekFrom::Start(dir_info.directory_start))?;
reader.seek(SeekFrom::Start(dir_info.directory_start))?;
for _ in 0..dir_info.number_of_files {
let file = central_header_to_zip_file(reader, dir_info.archive_offset)?;
files.push(file);
@ -925,7 +926,7 @@ impl<R: Read + Seek> ZipArchive<R> {
let mut file = self.by_index(i)?;
let filepath = file
.enclosed_name()
.ok_or(ZipError::InvalidArchive("Invalid file path"))?;
.ok_or(InvalidArchive("Invalid file path"))?;
let outpath = directory.as_ref().join(filepath);
@ -1333,7 +1334,7 @@ fn central_header_to_zip_file_inner<R: Read>(
let aes_enabled = result.compression_method == CompressionMethod::AES;
if aes_enabled && result.aes_mode.is_none() {
return Err(ZipError::InvalidArchive(
return Err(InvalidArchive(
"AES encryption without AES extra data field",
));
}
@ -1342,7 +1343,7 @@ fn central_header_to_zip_file_inner<R: Read>(
result.header_start = result
.header_start
.checked_add(archive_offset)
.ok_or(ZipError::InvalidArchive("Archive header is too large"))?;
.ok_or(InvalidArchive("Archive header is too large"))?;
Ok(result)
}
@ -1392,14 +1393,13 @@ pub(crate) fn parse_single_extra_field<R: Read>(
"Can't write a custom field using the ZIP64 ID",
));
}
file.large_file = true;
let mut consumed_len = 0;
if len >= 24 || file.uncompressed_size == spec::ZIP64_BYTES_THR {
file.large_file = true;
file.uncompressed_size = reader.read_u64_le()?;
consumed_len += size_of::<u64>();
}
if len >= 24 || file.compressed_size == spec::ZIP64_BYTES_THR {
file.large_file = true;
file.compressed_size = reader.read_u64_le()?;
consumed_len += size_of::<u64>();
}
@ -1428,18 +1428,18 @@ pub(crate) fn parse_single_extra_field<R: Read>(
let compression_method = CompressionMethod::parse_from_u16(reader.read_u16_le()?);
if vendor_id != 0x4541 {
return Err(ZipError::InvalidArchive("Invalid AES vendor"));
return Err(InvalidArchive("Invalid AES vendor"));
}
let vendor_version = match vendor_version {
0x0001 => AesVendorVersion::Ae1,
0x0002 => AesVendorVersion::Ae2,
_ => return Err(ZipError::InvalidArchive("Invalid AES vendor version")),
_ => return Err(InvalidArchive("Invalid AES vendor version")),
};
match aes_mode {
0x01 => file.aes_mode = Some((AesMode::Aes128, vendor_version, compression_method)),
0x02 => file.aes_mode = Some((AesMode::Aes192, vendor_version, compression_method)),
0x03 => file.aes_mode = Some((AesMode::Aes256, vendor_version, compression_method)),
_ => return Err(ZipError::InvalidArchive("Invalid AES encryption strength")),
_ => return Err(InvalidArchive("Invalid AES encryption strength")),
};
file.compression_method = compression_method;
file.aes_extra_data_start = bytes_already_read;
@ -1488,7 +1488,7 @@ pub trait HasZipMetadata {
/// Methods for retrieving information on zip files
impl<'a> ZipFile<'a> {
pub(crate) fn take_raw_reader(&mut self) -> io::Result<io::Take<&'a mut dyn Read>> {
std::mem::replace(&mut self.reader, ZipFileReader::NoReader).into_inner()
mem::replace(&mut self.reader, ZipFileReader::NoReader).into_inner()
}
/// Get the version of the file

View file

@ -50,7 +50,7 @@ use zstd::stream::write::Encoder as ZstdEncoder;
enum MaybeEncrypted<W> {
Unencrypted(W),
#[cfg(feature = "aes-crypto")]
Aes(crate::aes::AesWriter<W>),
Aes(AesWriter<W>),
ZipCrypto(crate::zipcrypto::ZipCryptoWriter<W>),
}
@ -173,9 +173,7 @@ pub(crate) mod zip_writer {
}
#[doc(inline)]
pub use self::sealed::FileOptionExtension;
use crate::result::ZipError::InvalidArchive;
#[cfg(any(feature = "lzma", feature = "xz"))]
use crate::result::ZipError::UnsupportedArchive;
use crate::result::ZipError::{InvalidArchive, UnsupportedArchive};
use crate::unstable::path_to_string;
use crate::unstable::LittleEndianWriteExt;
use crate::write::GenericZipWriter::{Closed, Storer};
@ -649,7 +647,7 @@ impl<A: Read + Write + Seek> ZipWriter<A> {
/// read previously-written files and not overwrite them.
///
/// Note: when using an `inner` that cannot overwrite flushed bytes, do not wrap it in a
/// [std::io::BufWriter], because that has a [Seek::seek] method that implicitly calls
/// [BufWriter], because that has a [Seek::seek] method that implicitly calls
/// [BufWriter::flush], and ZipWriter needs to seek backward to update each file's header with
/// the size and checksum after writing the body.
///
@ -859,7 +857,7 @@ impl<W: Write + Seek> ZipWriter<W> {
"No file has been started",
)));
}
self.stats.hasher = crc32fast::Hasher::new_with_initial_len(crc32, length);
self.stats.hasher = Hasher::new_with_initial_len(crc32, length);
self.stats.bytes_written = length;
Ok(())
}
@ -1005,11 +1003,11 @@ impl<W: Write + Seek> ZipWriter<W> {
#[cfg(feature = "aes-crypto")]
Some(EncryptWith::Aes { mode, password }) => {
let aeswriter = AesWriter::new(
mem::replace(&mut self.inner, GenericZipWriter::Closed).unwrap(),
mem::replace(&mut self.inner, Closed).unwrap(),
mode,
password.as_bytes(),
)?;
self.inner = GenericZipWriter::Storer(MaybeEncrypted::Aes(aeswriter));
self.inner = Storer(MaybeEncrypted::Aes(aeswriter));
}
Some(EncryptWith::ZipCrypto(keys, ..)) => {
let mut zipwriter = crate::zipcrypto::ZipCryptoWriter {
@ -1220,7 +1218,7 @@ impl<W: Write + Seek> ZipWriter<W> {
///```
pub fn merge_archive<R>(&mut self, mut source: ZipArchive<R>) -> ZipResult<()>
where
R: Read + io::Seek,
R: Read + Seek,
{
self.finish_file()?;
@ -1615,9 +1613,7 @@ impl<W: Write + Seek> GenericZipWriter<W> {
match compression {
Stored => {
if compression_level.is_some() {
Err(ZipError::UnsupportedArchive(
"Unsupported compression level",
))
Err(UnsupportedArchive("Unsupported compression level"))
} else {
Ok(Box::new(|bare| Storer(bare)))
}
@ -1637,9 +1633,8 @@ impl<W: Write + Seek> GenericZipWriter<W> {
compression_level.unwrap_or(default),
deflate_compression_level_range(),
)
.ok_or(ZipError::UnsupportedArchive(
"Unsupported compression level",
))? as u32;
.ok_or(UnsupportedArchive("Unsupported compression level"))?
as u32;
#[cfg(feature = "deflate-zopfli")]
{
@ -1681,18 +1676,17 @@ impl<W: Write + Seek> GenericZipWriter<W> {
}
}
#[cfg(feature = "deflate64")]
CompressionMethod::Deflate64 => Err(ZipError::UnsupportedArchive(
"Compressing Deflate64 is not supported",
)),
CompressionMethod::Deflate64 => {
Err(UnsupportedArchive("Compressing Deflate64 is not supported"))
}
#[cfg(feature = "bzip2")]
CompressionMethod::Bzip2 => {
let level = clamp_opt(
compression_level.unwrap_or(bzip2::Compression::default().level() as i64),
bzip2_compression_level_range(),
)
.ok_or(ZipError::UnsupportedArchive(
"Unsupported compression level",
))? as u32;
.ok_or(UnsupportedArchive("Unsupported compression level"))?
as u32;
Ok(Box::new(move |bare| {
GenericZipWriter::Bzip2(BzEncoder::new(
bare,
@ -1700,7 +1694,7 @@ impl<W: Write + Seek> GenericZipWriter<W> {
))
}))
}
CompressionMethod::AES => Err(ZipError::UnsupportedArchive(
CompressionMethod::AES => Err(UnsupportedArchive(
"AES encryption is enabled through FileOptions::with_aes_encryption",
)),
#[cfg(feature = "zstd")]
@ -1709,9 +1703,7 @@ impl<W: Write + Seek> GenericZipWriter<W> {
compression_level.unwrap_or(zstd::DEFAULT_COMPRESSION_LEVEL as i64),
zstd::compression_level_range(),
)
.ok_or(ZipError::UnsupportedArchive(
"Unsupported compression level",
))?;
.ok_or(UnsupportedArchive("Unsupported compression level"))?;
Ok(Box::new(move |bare| {
GenericZipWriter::Zstd(ZstdEncoder::new(bare, level as i32).unwrap())
}))
@ -1725,7 +1717,7 @@ impl<W: Write + Seek> GenericZipWriter<W> {
Err(UnsupportedArchive("XZ isn't supported for compression"))
}
CompressionMethod::Unsupported(..) => {
Err(ZipError::UnsupportedArchive("Unsupported compression"))
Err(UnsupportedArchive("Unsupported compression"))
}
}
}
@ -1777,7 +1769,7 @@ impl<W: Write + Seek> GenericZipWriter<W> {
}
const fn is_closed(&self) -> bool {
matches!(*self, GenericZipWriter::Closed)
matches!(*self, Closed)
}
fn get_plain(&mut self) -> &mut W {
@ -1832,17 +1824,14 @@ fn clamp_opt<T: Ord + Copy, U: Ord + Copy + TryFrom<T>>(
}
}
fn update_aes_extra_data<W: Write + io::Seek>(
writer: &mut W,
file: &mut ZipFileData,
) -> ZipResult<()> {
fn update_aes_extra_data<W: Write + Seek>(writer: &mut W, file: &mut ZipFileData) -> ZipResult<()> {
let Some((aes_mode, version, compression_method)) = file.aes_mode else {
return Ok(());
};
let extra_data_start = file.extra_data_start.unwrap();
writer.seek(io::SeekFrom::Start(
writer.seek(SeekFrom::Start(
extra_data_start + file.aes_extra_data_start,
))?;
@ -1925,7 +1914,7 @@ fn write_local_zip64_extra_field<T: Write>(writer: &mut T, file: &ZipFileData) -
// This entry in the Local header MUST include BOTH original
// and compressed file size fields.
let Some(block) = file.zip64_extra_field_block() else {
return Err(ZipError::InvalidArchive(
return Err(InvalidArchive(
"Attempted to write a ZIP64 extra field for a file that's within zip32 limits",
));
};
@ -1938,19 +1927,15 @@ fn update_local_zip64_extra_field<T: Write + Seek>(
writer: &mut T,
file: &ZipFileData,
) -> ZipResult<()> {
if !file.large_file {
return Err(ZipError::InvalidArchive(
"Attempted to update a nonexistent ZIP64 extra field",
));
}
let block = file.zip64_extra_field_block().ok_or(InvalidArchive(
"Attempted to update a nonexistent ZIP64 extra field",
))?;
let zip64_extra_field = file.header_start
+ mem::size_of::<ZipLocalEntryBlock>() as u64
let zip64_extra_field_start = file.header_start
+ size_of::<ZipLocalEntryBlock>() as u64
+ file.file_name_raw.len() as u64;
writer.seek(SeekFrom::Start(zip64_extra_field))?;
let block = file.zip64_extra_field_block().unwrap();
writer.seek(SeekFrom::Start(zip64_extra_field_start))?;
let block = block.serialize();
writer.write_all(&block)?;
Ok(())
@ -1994,14 +1979,13 @@ mod test {
use crate::zipcrypto::ZipCryptoKeys;
use crate::CompressionMethod::Stored;
use crate::ZipArchive;
use std::io;
use std::io::{Cursor, Read, Write};
use std::marker::PhantomData;
use std::path::PathBuf;
#[test]
fn write_empty_zip() {
let mut writer = ZipWriter::new(io::Cursor::new(Vec::new()));
let mut writer = ZipWriter::new(Cursor::new(Vec::new()));
writer.set_comment("ZIP");
let result = writer.finish().unwrap();
assert_eq!(result.get_ref().len(), 25);
@ -2020,7 +2004,7 @@ mod test {
#[test]
fn write_zip_dir() {
let mut writer = ZipWriter::new(io::Cursor::new(Vec::new()));
let mut writer = ZipWriter::new(Cursor::new(Vec::new()));
writer
.add_directory(
"test",
@ -2048,7 +2032,7 @@ mod test {
#[test]
fn write_symlink_simple() {
let mut writer = ZipWriter::new(io::Cursor::new(Vec::new()));
let mut writer = ZipWriter::new(Cursor::new(Vec::new()));
writer
.add_symlink(
"name",
@ -2083,7 +2067,7 @@ mod test {
path.push("..");
path.push(".");
path.push("example.txt");
let mut writer = ZipWriter::new(io::Cursor::new(Vec::new()));
let mut writer = ZipWriter::new(Cursor::new(Vec::new()));
writer
.start_file_from_path(path, SimpleFileOptions::default())
.unwrap();
@ -2093,7 +2077,7 @@ mod test {
#[test]
fn write_symlink_wonky_paths() {
let mut writer = ZipWriter::new(io::Cursor::new(Vec::new()));
let mut writer = ZipWriter::new(Cursor::new(Vec::new()));
writer
.add_symlink(
"directory\\link",
@ -2125,9 +2109,9 @@ mod test {
#[test]
fn write_mimetype_zip() {
let mut writer = ZipWriter::new(io::Cursor::new(Vec::new()));
let mut writer = ZipWriter::new(Cursor::new(Vec::new()));
let options = FileOptions {
compression_method: CompressionMethod::Stored,
compression_method: Stored,
compression_level: None,
last_modified_time: DateTime::default(),
permissions: Some(33188),
@ -2162,9 +2146,9 @@ mod test {
#[test]
fn write_non_utf8() {
let mut writer = ZipWriter::new(io::Cursor::new(Vec::new()));
let mut writer = ZipWriter::new(Cursor::new(Vec::new()));
let options = FileOptions {
compression_method: CompressionMethod::Stored,
compression_method: Stored,
compression_level: None,
last_modified_time: DateTime::default(),
permissions: Some(33188),
@ -2199,7 +2183,7 @@ mod test {
#[test]
fn path_to_string() {
let mut path = std::path::PathBuf::new();
let mut path = PathBuf::new();
#[cfg(windows)]
path.push(r"C:\");
#[cfg(unix)]
@ -2214,7 +2198,7 @@ mod test {
#[test]
fn test_shallow_copy() {
let mut writer = ZipWriter::new(io::Cursor::new(Vec::new()));
let mut writer = ZipWriter::new(Cursor::new(Vec::new()));
let options = FileOptions {
compression_method: CompressionMethod::default(),
compression_level: None,
@ -2264,7 +2248,7 @@ mod test {
#[test]
fn test_deep_copy() {
let mut writer = ZipWriter::new(io::Cursor::new(Vec::new()));
let mut writer = ZipWriter::new(Cursor::new(Vec::new()));
let options = FileOptions {
compression_method: CompressionMethod::default(),
compression_level: None,
@ -2312,7 +2296,7 @@ mod test {
#[test]
fn duplicate_filenames() {
let mut writer = ZipWriter::new(io::Cursor::new(Vec::new()));
let mut writer = ZipWriter::new(Cursor::new(Vec::new()));
writer
.start_file("foo/bar/test", SimpleFileOptions::default())
.unwrap();
@ -2326,7 +2310,7 @@ mod test {
#[test]
fn test_filename_looks_like_zip64_locator() {
let mut writer = ZipWriter::new(io::Cursor::new(Vec::new()));
let mut writer = ZipWriter::new(Cursor::new(Vec::new()));
writer
.start_file(
"PK\u{6}\u{7}\0\0\0\u{11}\0\0\0\0\0\0\0\0\0\0\0\0",
@ -2339,7 +2323,7 @@ mod test {
#[test]
fn test_filename_looks_like_zip64_locator_2() {
let mut writer = ZipWriter::new(io::Cursor::new(Vec::new()));
let mut writer = ZipWriter::new(Cursor::new(Vec::new()));
writer
.start_file(
"PK\u{6}\u{6}\0\0\0\0\0\0\0\0\0\0PK\u{6}\u{7}\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0",
@ -2352,7 +2336,7 @@ mod test {
#[test]
fn test_filename_looks_like_zip64_locator_2a() {
let mut writer = ZipWriter::new(io::Cursor::new(Vec::new()));
let mut writer = ZipWriter::new(Cursor::new(Vec::new()));
writer
.start_file(
"PK\u{6}\u{6}PK\u{6}\u{7}\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0",
@ -2365,7 +2349,7 @@ mod test {
#[test]
fn test_filename_looks_like_zip64_locator_3() {
let mut writer = ZipWriter::new(io::Cursor::new(Vec::new()));
let mut writer = ZipWriter::new(Cursor::new(Vec::new()));
writer
.start_file("\0PK\u{6}\u{6}", SimpleFileOptions::default())
.unwrap();
@ -2381,7 +2365,7 @@ mod test {
#[test]
fn test_filename_looks_like_zip64_locator_4() {
let mut writer = ZipWriter::new(io::Cursor::new(Vec::new()));
let mut writer = ZipWriter::new(Cursor::new(Vec::new()));
writer
.start_file("PK\u{6}\u{6}", SimpleFileOptions::default())
.unwrap();
@ -2407,7 +2391,7 @@ mod test {
#[test]
fn test_filename_looks_like_zip64_locator_5() -> ZipResult<()> {
let mut writer = ZipWriter::new(io::Cursor::new(Vec::new()));
let mut writer = ZipWriter::new(Cursor::new(Vec::new()));
writer
.add_directory("", SimpleFileOptions::default().with_alignment(21))
.unwrap();
@ -2433,7 +2417,7 @@ mod test {
#[test]
fn remove_shallow_copy_keeps_original() -> ZipResult<()> {
let mut writer = ZipWriter::new(io::Cursor::new(Vec::new()));
let mut writer = ZipWriter::new(Cursor::new(Vec::new()));
writer
.start_file("original", SimpleFileOptions::default())
.unwrap();
@ -2452,7 +2436,7 @@ mod test {
#[test]
fn remove_encrypted_file() -> ZipResult<()> {
let mut writer = ZipWriter::new(io::Cursor::new(Vec::new()));
let mut writer = ZipWriter::new(Cursor::new(Vec::new()));
let first_file_options = SimpleFileOptions::default()
.with_alignment(65535)
.with_deprecated_encryption(b"Password");
@ -2469,7 +2453,7 @@ mod test {
let mut options = SimpleFileOptions::default();
options = options.with_deprecated_encryption(b"Password");
options.alignment = 65535;
let mut writer = ZipWriter::new(io::Cursor::new(Vec::new()));
let mut writer = ZipWriter::new(Cursor::new(Vec::new()));
writer.add_symlink("", "s\t\0\0ggggg\0\0", options).unwrap();
writer.abort_file().unwrap();
let zip = writer.finish().unwrap();
@ -2485,7 +2469,7 @@ mod test {
options = options
.compression_method(CompressionMethod::default())
.compression_level(Some(264));
let mut writer = ZipWriter::new(io::Cursor::new(Vec::new()));
let mut writer = ZipWriter::new(Cursor::new(Vec::new()));
writer.start_file("", options).unwrap();
writer.write_all(&[]).unwrap();
writer.write_all(&[]).unwrap();
@ -2495,11 +2479,9 @@ mod test {
#[test]
fn crash_with_no_features() -> ZipResult<()> {
const ORIGINAL_FILE_NAME: &str = "PK\u{6}\u{6}\0\0\0\0\0\0\0\0\0\u{2}g\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\u{1}\0\0\0\0\0\0\0\0\0\0PK\u{6}\u{7}\0\0\0\0\0\0\0\0\0\0\0\0\u{7}\0\t'";
let mut writer = ZipWriter::new(io::Cursor::new(Vec::new()));
let mut writer = ZipWriter::new(Cursor::new(Vec::new()));
let mut options = SimpleFileOptions::default();
options = options
.with_alignment(3584)
.compression_method(CompressionMethod::Stored);
options = options.with_alignment(3584).compression_method(Stored);
writer.start_file(ORIGINAL_FILE_NAME, options)?;
let archive = writer.finish()?;
let mut writer = ZipWriter::new_append(archive)?;
@ -2512,9 +2494,9 @@ mod test {
fn test_alignment() {
let page_size = 4096;
let options = SimpleFileOptions::default()
.compression_method(CompressionMethod::Stored)
.compression_method(Stored)
.with_alignment(page_size);
let mut zip = ZipWriter::new(io::Cursor::new(Vec::new()));
let mut zip = ZipWriter::new(Cursor::new(Vec::new()));
let contents = b"sleeping";
let () = zip.start_file("sleep", options).unwrap();
let _count = zip.write(&contents[..]).unwrap();