1use onestore::{PropertySets, Reference, Store};
2use std::{env, fs};
3
4fn main() -> Result<(), Box<dyn std::error::Error>> {
5 for path in env::args_os().skip(1) {
6 let bytes = fs::read(&path)?;
7 let store = Store::parse(&bytes)?;
8 let mut count = 0;
9 for list in store.lists.values() {
10 for node in &list.nodes {
11 if node.id == 0x7c {
12 return Err("Encrypted object space requires revision-aware inspection".into());
13 }
14 if matches!(
15 node.id,
16 0xa4 | 0xa5 | 0xc4 | 0xc5 | 0x2d | 0x2e | 0x41 | 0x42
17 ) && let Some(Reference::Data(chunk)) = node.reference
18 {
19 let start = usize::try_from(chunk.offset)?;
20 let end = start
21 .checked_add(usize::try_from(chunk.length)?)
22 .ok_or("Property range exceeds address space")?;
23 let properties = PropertySets::parse(
24 bytes
25 .get(start..end)
26 .ok_or("Property range extends outside the file")?,
27 )
28 .map_err(|error| {
29 format!(
30 "{:?}, node {:#x}, data {start:#x}: {error}",
31 path, node.offset
32 )
33 })?;
34 count += properties.sets.iter().map(Vec::len).sum::<usize>();
35 }
36 }
37 }
38 println!("{:?}: {count} properties", path);
39 }
40 Ok(())
41}