Skip to content
Open
28 changes: 26 additions & 2 deletions fuzz_write/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use std::io::Write as IoWrite;
use std::io::{Cursor, Seek, SeekFrom};
use std::path::PathBuf;
use tikv_jemallocator::Jemalloc;
use zip::read::read_zipfile_from_stream;
use zip::result::{ZipError, ZipResult};
use zip::unstable::path_to_string;
use zip::write::FullFileOptions;
Expand Down Expand Up @@ -61,6 +62,19 @@ impl FileOperation<'_> {
_ => Some(self.path.to_owned()),
}
}

fn is_streamable(&self) -> bool {
match &self.basic {
BasicFileOperation::WriteNormalFile {options, ..} => !options.has_encryption(),
BasicFileOperation::WriteDirectory(options) => !options.has_encryption(),
BasicFileOperation::WriteSymlinkWithTarget {options, ..} => !options.has_encryption(),
BasicFileOperation::ShallowCopy(base) => base.is_streamable(),
BasicFileOperation::DeepCopy(base) => base.is_streamable(),
BasicFileOperation::MergeWithOtherFile {operations, initial_junk} =>
initial_junk.is_empty() && operations.iter().all(|(op, _)| op.is_streamable()),
_ => true
}
}
}

#[derive(Arbitrary, Clone)]
Expand Down Expand Up @@ -201,7 +215,7 @@ fn do_operation(
"let sub_writer = {{\n\
let mut initial_junk = Cursor::new(vec!{initial_junk:?});\n\
initial_junk.seek(SeekFrom::End(0))?;
let mut writer = ZipWriter::new(initial_junk);",
let mut writer = ZipWriter::new(initial_junk);",/
)?;
}
let mut initial_junk = Cursor::new(initial_junk.into_vec());
Expand Down Expand Up @@ -293,6 +307,7 @@ fn do_operation(

impl FuzzTestCase<'_> {
fn execute(self, stringifier: &mut impl Write, panic_on_error: bool) -> ZipResult<()> {
let junk_len = self.initial_junk.len();
let mut initial_junk = Cursor::new(self.initial_junk.into_vec());
initial_junk.seek(SeekFrom::End(0))?;
let mut writer = zip::ZipWriter::new(initial_junk);
Expand All @@ -303,6 +318,7 @@ impl FuzzTestCase<'_> {
final_reopen = true;
}
}
let streamable = self.operations.iter().all(|(op, _)| op.is_streamable());
#[allow(unknown_lints)]
#[allow(boxed_slice_into_iter)]
for (operation, abort) in self.operations.into_vec().into_iter() {
Expand All @@ -316,7 +332,15 @@ impl FuzzTestCase<'_> {
panic_on_error,
);
}
if final_reopen {
if streamable {
writeln!(stringifier, "let mut stream = writer.finish()?;\n\
stream.seek(SeekFrom::Start({junk_len}))?;\n\
while read_zipfile_from_stream(&mut stream)?.is_some() {{}}")
.map_err(|_| ZipError::InvalidArchive("Failed to read from stream".into()))?;
let mut stream = writer.finish()?;
stream.seek(SeekFrom::Start(junk_len as u64))?;
while read_zipfile_from_stream(&mut stream)?.is_some() {}
} else if final_reopen {
writeln!(stringifier, "let _ = writer.finish_into_readable()?;")
.map_err(|_| ZipError::InvalidArchive("".into()))?;
let _ = writer.finish_into_readable()?;
Expand Down
Loading