zip_extensions/audit/handlers/
entry_view.rs1use crate::audit::handlers::util;
2use std::io::{Read, Seek};
3use std::path::PathBuf;
4use zip::read::ZipFile;
5
6#[derive(Debug, Clone)]
8pub struct EntryView {
9 pub compressed_size: u64,
10 pub depth_hint: usize,
11 pub enclosed_name: PathBuf,
12 pub encrypted: bool,
13 pub has_abs: bool,
14 pub has_parent_components: bool,
15 pub invalid_utf8: bool,
16 pub name_raw: Vec<u8>,
17 pub ratio: f64,
18 pub symlink: bool,
19 pub symlink_target: Option<String>,
20 pub uncompressed_size: u64,
21 pub unix_mode: Option<u32>,
22}
23
24impl EntryView {
25 pub fn from_entry<R: Read + Seek>(mut entry: ZipFile<R>) -> Self {
30 let name_raw_slice: &[u8] = entry.name_raw();
32 let (name_raw, utf8_opt) = util::name_raw_and_utf8(name_raw_slice);
33 let invalid_utf8 = utf8_opt.is_none();
34 let enclosed_name = entry.mangled_name();
35
36 let has_abs = util::is_absolute_path_bytes(&name_raw);
37 let has_parent = util::has_parent_components_bytes(&name_raw);
38 let depth_hint = util::depth_hint_bytes(&name_raw);
39
40 let compressed_size = entry.compressed_size();
41 let uncompressed_size = entry.size();
42 let ratio = util::compression_ratio(compressed_size, uncompressed_size);
43
44 let encrypted = entry.encrypted();
45
46 let unix_mode = entry.unix_mode();
47 let symlink = util::is_symlink_unix_mode(unix_mode);
48 let mut symlink_target: Option<String> = None;
49 const SAFE_UNCOMPRESSED_SIZE_LIMIT: u64 = 8192;
50 if symlink && uncompressed_size <= SAFE_UNCOMPRESSED_SIZE_LIMIT {
51 let mut target = String::new();
52 let _ = entry.read_to_string(&mut target);
53 if !target.is_empty() {
54 symlink_target = Some(target);
55 }
56 }
57
58 let view = EntryView {
59 compressed_size,
60 depth_hint,
61 enclosed_name,
62 encrypted,
63 has_abs,
64 has_parent_components: has_parent,
65 invalid_utf8,
66 name_raw,
67 ratio,
68 symlink,
69 symlink_target,
70 uncompressed_size,
71 unix_mode,
72 };
73
74 view
75 }
76}