in mp4parse/src/lib.rs [3478:3508]
fn calculate_ipma_total_associations(
version: u8,
bytes_left: u64,
entry_count: U32,
num_association_bytes: std::num::NonZeroU8,
) -> Result<usize> {
let min_entry_bytes =
std::num::NonZeroU8::new(1 /* association_count */ + if version == 0 { 2 } else { 4 })
.unwrap();
let total_non_association_bytes: U32MulU8 = entry_count * min_entry_bytes;
let total_association_bytes: u64 =
if let Some(difference) = bytes_left.checked_sub(total_non_association_bytes.get()) {
// All the storage for the `essential` and `property_index` parts (assuming a valid ipma box size)
difference
} else {
return Status::IpmaTooSmall.into();
};
let max_association_bytes_per_entry: U16 = MAX_IPMA_ASSOCIATION_COUNT * num_association_bytes;
let max_total_association_bytes: U32MulU16 = entry_count * max_association_bytes_per_entry;
let max_bytes_left: U64 = total_non_association_bytes + max_total_association_bytes;
if bytes_left > max_bytes_left.get() {
return Status::IpmaTooBig.into();
}
let total_associations: u64 = total_association_bytes / u64::from(num_association_bytes.get());
Ok(total_associations.try_into()?)
}