Bug fix: skip invalid filenames during write fuzz
This commit is contained in:
parent
dc351196e2
commit
bf867c5012
3 changed files with 25 additions and 18 deletions
|
@ -24,6 +24,7 @@ pbkdf2 = {version = "0.12.1", optional = true }
|
|||
sha1 = {version = "0.10.5", optional = true }
|
||||
time = { version = "0.3.21", optional = true, default-features = false, features = ["std"] }
|
||||
zstd = { version = "0.12.3", optional = true }
|
||||
visibility = "0.0.1"
|
||||
|
||||
[target.'cfg(any(all(target_arch = "arm", target_pointer_width = "32"), target_arch = "mips", target_arch = "powerpc"))'.dependencies]
|
||||
crossbeam-utils = "0.8.15"
|
||||
|
|
|
@ -51,6 +51,9 @@ impl FileOperation {
|
|||
fn do_operation<T>(writer: &mut RefCell<zip_next::ZipWriter<T>>,
|
||||
operation: &FileOperation) -> Result<(), Box<dyn std::error::Error>>
|
||||
where T: Read + Write + Seek {
|
||||
if zip_next::write::validate_name(&operation.get_name()).is_err() {
|
||||
return Ok(());
|
||||
}
|
||||
match operation {
|
||||
FileOperation::Write {file, mut options, ..} => {
|
||||
if file.contents.iter().map(Vec::len).sum::<usize>() >= u32::MAX as usize {
|
||||
|
|
39
src/write.rs
39
src/write.rs
|
@ -439,7 +439,7 @@ impl<W: Write + Seek> ZipWriter<W> {
|
|||
{
|
||||
let header_start = self.inner.get_plain().stream_position()?;
|
||||
let name = name.into();
|
||||
Self::validate_name(&name)?;
|
||||
validate_name(&name)?;
|
||||
|
||||
let permissions = options.permissions.unwrap_or(0o100644);
|
||||
let file = ZipFileData {
|
||||
|
@ -1032,27 +1032,30 @@ impl<W: Write + Seek> ZipWriter<W> {
|
|||
self.insert_file_data(dest_data)?;
|
||||
Ok(())
|
||||
}
|
||||
fn validate_name(name: &String) -> ZipResult<()> {
|
||||
for (index, _) in name.match_indices("PK") {
|
||||
if name.len() >= index + 4 {
|
||||
let magic_number = name[index..index + 4]
|
||||
.as_bytes()
|
||||
.read_u32::<LittleEndian>()?;
|
||||
match magic_number {
|
||||
spec::ZIP64_CENTRAL_DIRECTORY_END_SIGNATURE => {
|
||||
return Err(InvalidArchive("Filename can't contain ZIP64 end signature"));
|
||||
}
|
||||
spec::ZIP64_CENTRAL_DIRECTORY_END_LOCATOR_SIGNATURE => {
|
||||
return Err(InvalidArchive(
|
||||
"Filename can't contain ZIP64 end-locator signature",
|
||||
));
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
#[cfg_attr(fuzzing, visibility::make(pub))]
|
||||
#[cfg_attr(fuzzing, allow(missing_docs))]
|
||||
pub(crate) fn validate_name(name: &String) -> ZipResult<()> {
|
||||
for (index, _) in name.match_indices("PK") {
|
||||
if name.len() >= index + 4 {
|
||||
let magic_number = name[index..index + 4]
|
||||
.as_bytes()
|
||||
.read_u32::<LittleEndian>()?;
|
||||
match magic_number {
|
||||
spec::ZIP64_CENTRAL_DIRECTORY_END_SIGNATURE => {
|
||||
return Err(InvalidArchive("Filename can't contain ZIP64 end signature"));
|
||||
}
|
||||
spec::ZIP64_CENTRAL_DIRECTORY_END_LOCATOR_SIGNATURE => {
|
||||
return Err(InvalidArchive(
|
||||
"Filename can't contain ZIP64 end-locator signature",
|
||||
));
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
impl<W: Write + Seek> Drop for ZipWriter<W> {
|
||||
|
|
Loading…
Add table
Reference in a new issue