Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 16 additions & 16 deletions src/spec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,32 +108,32 @@ impl ExtraFieldMagic {
///
/// let mut zip = ZipWriter::new(Cursor::new(Vec::new()));
/// // Writing an extremely large file for this test is faster without compression.
/// let options = SimpleFileOptions::default().compression_method(zip::CompressionMethod::Stored);
///
/// let big_len: usize = (zip::ZIP64_BYTES_THR as usize) + 1;
/// let big_buf = vec![0u8; big_len];
/// {
/// zip.start_file("zero.dat", options)?;
/// // This is too big!
/// let res = zip.write_all(&big_buf[..]).err().unwrap();
/// assert_eq!(res.kind(), io::ErrorKind::Other);
/// let description = format!("{}", &res);
/// assert_eq!(description, "Large file option has not been set");
/// }
/// {
/// // Attempting to write anything further to the same zip will still succeed, but the previous
/// // failing entry has been removed.
/// zip.start_file("one.dat", options)?;
/// let zip = zip.finish_into_readable()?;
/// let names: Vec<_> = zip.file_names().collect();
/// assert_eq!(&names, &["one.dat"]);
/// let options = SimpleFileOptions::default()
/// .compression_method(zip::CompressionMethod::Stored);
/// zip.start_file("zero.dat", options)?;
/// // This is too big!
/// let res = zip.write_all(&big_buf[..]).err().unwrap();
/// assert_eq!(res.kind(), io::ErrorKind::Other);
/// let description = format!("{}", &res);
/// assert_eq!(description, "Large file option has not been set");
/// // Attempting to write anything further to the same zip will still succeed, but the previous
/// // failing entry has been removed.
/// zip.start_file("one.dat", options)?;
/// let zip = zip.finish_into_readable()?;
/// let names: Vec<_> = zip.file_names().collect();
/// assert_eq!(&names, &["one.dat"]);
/// }
///
/// // Create a new zip output.
/// let mut zip = ZipWriter::new(Cursor::new(Vec::new()));
/// // This time, create a zip64 record for the file.
/// let options = SimpleFileOptions::default()
/// .compression_method(zip::CompressionMethod::Stored).large_file(true);
/// .compression_method(zip::CompressionMethod::Stored)
/// .large_file(true);
/// zip.start_file("zero.dat", options)?;
/// // This succeeds because we specified that it could be a large file.
/// assert!(zip.write_all(&big_buf[..]).is_ok());
Expand Down
11 changes: 11 additions & 0 deletions src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -959,10 +959,21 @@ impl ZipFileData {
pub(crate) fn write_data_descriptor<W: std::io::Write>(
&self,
writer: &mut W,
auto_large_file: bool,
) -> Result<(), ZipError> {
if self.large_file {
return self.zip64_data_descriptor_block().write(writer);
}
if self.compressed_size > spec::ZIP64_BYTES_THR
|| self.uncompressed_size > spec::ZIP64_BYTES_THR
{
if auto_large_file {
return self.zip64_data_descriptor_block().write(writer);
}
return Err(ZipError::Io(std::io::Error::other(
"Large file option has not been set - use .large_file(true) in options",
)));
}
self.data_descriptor_block().write(writer)
}

Expand Down
12 changes: 11 additions & 1 deletion src/write.rs
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,7 @@ pub(crate) mod zip_writer {
pub(super) zip64_comment: Option<Box<[u8]>>,
pub(super) flush_on_finish_file: bool,
pub(super) seek_possible: bool,
pub(crate) auto_large_file: bool,
}

impl<W: Write + Seek> Debug for ZipWriter<W> {
Expand Down Expand Up @@ -650,6 +651,7 @@ impl<A: Read + Write + Seek> ZipWriter<A> {
writing_raw: true, // avoid recomputing the last file's header
flush_on_finish_file: false,
seek_possible: true,
auto_large_file: false,
})
}

Expand Down Expand Up @@ -808,9 +810,16 @@ impl<W: Write + Seek> ZipWriter<W> {
zip64_comment: None,
flush_on_finish_file: false,
seek_possible: true,
auto_large_file: false,
}
}

/// Set automatically large file to true if needed
pub fn set_auto_large_file(mut self) -> Self {
self.auto_large_file = true;
self
}

/// Returns true if a file is currently open for writing.
pub const fn is_writing_file(&self) -> bool {
self.writing_to_file && !self.inner.is_closed()
Expand Down Expand Up @@ -1111,7 +1120,7 @@ impl<W: Write + Seek> ZipWriter<W> {
};
update_aes_extra_data(writer, file)?;
if file.using_data_descriptor {
file.write_data_descriptor(writer)?;
file.write_data_descriptor(writer, self.auto_large_file)?;
} else {
update_local_file_header(writer, file)?;
writer.seek(SeekFrom::Start(file_end))?;
Expand Down Expand Up @@ -1658,6 +1667,7 @@ impl<W: Write> ZipWriter<StreamWriter<W>> {
zip64_comment: None,
flush_on_finish_file: false,
seek_possible: false,
auto_large_file: false,
}
}
}
Expand Down