Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
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
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ The zip creation fuzzer will try to print out a description of the kind of input
# This input was translated into one or more test cases:
<fuzz/write/in/id-000000,time-0,execs-0,orig-0011743621118ab6c5278ffbb8fd14bddd8369ee.min \
cargo run --manifest-path=fuzz/Cargo.toml --quiet -p fuzz_write
writer.start_file_from_path("", FileOptions { compression_method: Stored, compression_level: None, last_modified_time: DateTime::from_date_and_time(2048, 1, 1, 0, 0, 0)?, permissions: None, large_file: false, encrypt_with: None, extended_options: ExtendedFileOptions {extra_data: vec![].into(), central_extra_data: vec![].into()}, alignment: 0 })?;
writer.start_file_from_path("", FileOptions { compression_method: Stored, compression_level: None, last_modified_time: DateTime::from_date_and_time(2048, 1, 1, 0, 0, 0)?, permissions: None, large_file: false, encrypt_with: None, extended_options: ExtendedFileOptions {extra_fields: vec![].into()}, alignment: 0 })?;
Comment thread
Its-Just-Nans marked this conversation as resolved.
writer.write_all(&[])?;
writer
let _ = writer.finish_into_readable()?;
Expand Down
59 changes: 59 additions & 0 deletions src/extra_fields/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
//! Types for extra fields

use crate::result::ZipResult;
use crate::result::invalid;
use core::fmt::Display;

mod aex_encryption;
Expand Down Expand Up @@ -180,3 +182,60 @@ pub const EXTRA_FIELD_MAPPING: [u16; 59] = [
0xe57a, // Korean ZIP code page info
0xfd4a, // SMS/QDOS
];

#[derive(Debug, PartialEq, Eq, Clone)]
pub(crate) struct CustomExtraField {
pub(crate) central_only: bool,
header_id: u16,
data: Box<[u8]>,
}

impl CustomExtraField {
pub(crate) fn new(central_only: bool, header_id: u16, data: &[u8]) -> Self {
Self {
central_only,
header_id,
data: data.into(),
}
}

#[allow(unused)] // used for tests
pub(crate) fn new_from_raw(central_only: bool, data: &[u8]) -> ZipResult<Self> {
if data.len() < 2 {
return Err(invalid!("Cannot build a CustomExtraField: no header_id"));
}
let header_id = u16::from_le_bytes([data[0], data[1]]);
if data.len() < 4 {
return Err(invalid!("Cannot build a CustomExtraField: no size"));
}
Comment thread
Its-Just-Nans marked this conversation as resolved.
let size = u16::from_le_bytes([data[2], data[3]]) as usize;
Comment thread
Its-Just-Nans marked this conversation as resolved.
if size > u16::MAX as usize {
return Err(invalid!("Cannot build a CustomExtraField: size too big"));
}
Comment thread
Its-Just-Nans marked this conversation as resolved.
Outdated
let data_rest = &data[4..];
if size != data_rest.len() {
return Err(invalid!("Cannot build a CustomExtraField: incorrect size"));
}
Ok(Self {
central_only,
header_id,
data: data[2..].to_vec().into_boxed_slice(),
Comment thread
Its-Just-Nans marked this conversation as resolved.
Outdated
})
}

pub(crate) fn len(&self) -> usize {
Comment thread
Its-Just-Nans marked this conversation as resolved.
Outdated
let size = self.data.len();
2 + 2 + size
Comment thread
Its-Just-Nans marked this conversation as resolved.
Outdated
}

pub(crate) fn serialize(&self) -> Vec<u8> {
let mut out = Vec::with_capacity(4 + self.data.len());

out.extend_from_slice(&self.header_id.to_le_bytes());
let size = self.data.len() as u16;
out.extend_from_slice(&size.to_le_bytes());
out.extend_from_slice(&self.data);

out
}
}
4 changes: 2 additions & 2 deletions src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -404,8 +404,8 @@ impl ZipFileData {
extra_field: Some(Arc::from(extra_field)),
central_extra_field: options
.extended_options
.central_extra_data()
.map(|v| Arc::from(v.as_ref().as_slice())),
.central_extra_fields()
.map(Arc::<[u8]>::from),
file_comment: String::with_capacity(0).into_boxed_str(),
header_start,
data_start: OnceLock::new(),
Expand Down
Loading
Loading