zip/extra_fields/
zipinfo_utf8.rs1use crate::result::{ZipError, ZipResult};
2use crate::unstable::LittleEndianReadExt;
3use core::mem::size_of;
4use std::io::Read;
5
6#[derive(Clone, Debug)]
9pub struct UnicodeExtraField {
10 crc32: u32,
11 content: Box<[u8]>,
12}
13
14impl UnicodeExtraField {
15 pub fn unwrap_valid(self, ascii_field: &[u8]) -> ZipResult<Box<[u8]>> {
17 let mut crc32 = crc32fast::Hasher::new();
18 crc32.update(ascii_field);
19 let actual_crc32 = crc32.finalize();
20 if self.crc32 != actual_crc32 {
21 return Err(ZipError::InvalidArchive(
22 "CRC32 checksum failed on Unicode extra field",
23 ));
24 }
25 Ok(self.content)
26 }
27}
28
29impl UnicodeExtraField {
30 pub(crate) fn try_from_reader<R: Read>(reader: &mut R, len: u16) -> ZipResult<Self> {
31 reader.read_exact(&mut [0u8])?;
33
34 let crc32 = reader.read_u32_le()?;
35 let content_len = (len as usize)
36 .checked_sub(size_of::<u8>() + size_of::<u32>())
37 .ok_or(ZipError::InvalidArchive("Unicode extra field is too small"))?;
38 let mut content = vec![0u8; content_len].into_boxed_slice();
39 reader.read_exact(&mut content)?;
40 Ok(Self { crc32, content })
41 }
42}