pub struct ZipEntry<'archive, R> { /* private fields */ }Expand description
Represents a single entry (file or directory) within a ZipArchive
Implementations§
Source§impl<'archive, R> ZipEntry<'archive, R>where
R: ReaderAt,
impl<'archive, R> ZipEntry<'archive, R>where
R: ReaderAt,
Sourcepub fn reader(&self) -> ZipReader<&'archive R> ⓘ
pub fn reader(&self) -> ZipReader<&'archive R> ⓘ
Returns a ZipReader for reading the compressed data of this entry.
Sourcepub fn verifying_reader<D>(&self, reader: D) -> ZipVerifier<D, &'archive R> ⓘwhere
D: Read,
pub fn verifying_reader<D>(&self, reader: D) -> ZipVerifier<D, &'archive R> ⓘwhere
D: Read,
Returns a reader that wraps a decompressor and verify the size and CRC of the decompressed data once finished.
Sourcepub fn compressed_data_range(&self) -> (u64, u64)
pub fn compressed_data_range(&self) -> (u64, u64)
Returns a tuple of start and end byte offsets for the compressed data within the underlying reader.
This method uses the information from the local file header in its calculations.
§Security Usage
This method is useful for detecting overlapping entries, which are often used in zip bombs. By comparing the ranges returned by this method across multiple entries, you can identify when entries share compressed data:
let archive = ZipArchive::from_slice(data)?;
let mut ranges = Vec::new();
for entry_result in archive.entries() {
let entry = entry_result?;
let wayfinder = entry.wayfinder();
if let Ok(zip_entry) = archive.get_entry(wayfinder) {
ranges.push(zip_entry.compressed_data_range());
}
}
// Check for overlapping ranges
ranges.sort_by_key(|&(start, _)| start);
for window in ranges.windows(2) {
let (_, end1) = window[0];
let (start2, _) = window[1];
if end1 > start2 {
panic!("Warning: Overlapping entries detected!");
}
}Sourcepub fn local_header<'a>(
&self,
buffer: &'a mut [u8],
) -> Result<ZipLocalFileHeader<'a>, Error>
pub fn local_header<'a>( &self, buffer: &'a mut [u8], ) -> Result<ZipLocalFileHeader<'a>, Error>
Returns the local file header information.
This method reads the local file header to which may differ from the central directory data. Most ZIP tools use the central directory as authoritative, but access to local header data can be useful:
The local header may contain:
- Additional or different extra fields (richer timestamp data, etc.)
- Different filename than the central directory (security concern)
The buffer argument must be large enough to hold both the filename and extra fields from the local header or a too small error will be returned.
§Examples
// Test with filename mismatch test fixture
let file = File::open("assets/filename_mismatch_test.zip")?;
let mut buf = vec![0u8; RECOMMENDED_BUFFER_SIZE];
let archive = ZipArchive::from_file(file, &mut buf)?;
let mut entries = archive.entries(&mut buf);
let entry_header = entries.next_entry()?.unwrap();
// Central directory shows one filename
assert_eq!(entry_header.file_path().as_ref(), b"malware.exe");
let wayfinder = entry_header.wayfinder();
let entry = archive.get_entry(wayfinder)?;
// Read the local header
let mut local_buffer = vec![0u8; 1024];
let local_header = entry.local_header(&mut local_buffer)?;
// Local header shows different filename
assert_eq!(local_header.file_path().as_ref(), b"safe_file.txt");
// Access extra fields from local header
let mut found_fields = 0;
for (field_id, _data) in local_header.extra_fields() {
found_fields += 1;
// Could check for specific extra field types here
println!("Found extra field: {:04x}", field_id.as_u16());
}