Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 4 additions & 7 deletions src/me.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ impl FPTArea {
Gen2Partition::Dir(d) => Some(d.clone()),
_ => None,
})
.collect::<Vec<DirPartition>>();
.collect::<Vec<Box<DirPartition>>>();
dirs.iter()
.map(|d| (d.entry.name(), d.check_signature()))
.collect()
Expand All @@ -104,14 +104,14 @@ impl FPTArea {
pub fn check_ftpr_presence(&self) -> Result<(), String> {
match &self.partitions {
Partitions::Gen2(parts) => {
if parts.iter().find(|p| p.entry().name() == FTPR).is_some() {
if parts.iter().any(|p| p.entry().name() == FTPR) {
Ok(())
} else {
Err("not found".into())
}
}
Partitions::Gen3(parts) => {
if parts.iter().find(|p| p.entry().name() == FTPR).is_some() {
if parts.iter().any(|p| p.entry().name() == FTPR) {
Ok(())
} else {
Err("not found".into())
Expand Down Expand Up @@ -190,10 +190,7 @@ impl FPTArea {
println!("Recreate ME region from components");
}

let mut res = match self.partitions.to_vec() {
Ok(r) => r,
Err(e) => return Err(e),
};
let mut res = self.partitions.to_vec()?;
if debug {
println!(" Minimum size: {:08x}", res.len());
}
Expand Down
31 changes: 13 additions & 18 deletions src/part/fpt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@ use zerocopy::{AlignmentError, ConvertError, FromBytes, IntoBytes, Ref, SizeErro
use zerocopy_derive::{FromBytes, Immutable, IntoBytes};

use crate::{
part::part::{retain, ClearOptions},
ver::Version,
EMPTY,
part::part::{ClearOptions, retain},
ver::Version,
};

pub const FTPR: &str = "FTPR";
Expand Down Expand Up @@ -142,16 +142,13 @@ impl Display for FPTHeader {
}
}

type EntryConvertError<'a> =
ConvertError<AlignmentError<&'a [u8], [FPTEntry]>, SizeError<&'a [u8], [FPTEntry]>, Infallible>;

#[derive(Debug)]
pub enum FptError<'a> {
ParseHeaderError(SizeError<&'a [u8], FPTHeader>),
ParseEntryError(
ConvertError<
AlignmentError<&'a [u8], [FPTEntry]>,
SizeError<&'a [u8], [FPTEntry]>,
Infallible,
>,
),
ParseEntryError(EntryConvertError<'a>),
}

#[derive(Serialize, Deserialize, Clone, Copy, Debug, Eq, PartialEq)]
Expand Down Expand Up @@ -293,22 +290,20 @@ const POSSIBLE_OFFSET: usize = 16;
fn determine_offset(data: &[u8]) -> Option<usize> {
let m = &data[..FPT_MAGIC_BYTES.len()];
if m.eq(FPT_MAGIC_BYTES) {
return Some(0);
Some(0)
} else {
let m = &data[POSSIBLE_OFFSET..POSSIBLE_OFFSET + FPT_MAGIC_BYTES.len()];
if m.eq(FPT_MAGIC_BYTES) {
return Some(POSSIBLE_OFFSET);
Some(POSSIBLE_OFFSET)
} else {
return None;
None
}
}
}

impl<'a> FPT {
pub fn parse(data: &'a [u8]) -> Option<Result<Self, FptError<'a>>> {
let Some(offset) = determine_offset(data) else {
return None;
};
let offset = determine_offset(data)?;
// Save for checksum recalculation
let pre_header = &data[..offset];
let d = &data[offset..];
Expand Down Expand Up @@ -353,7 +348,7 @@ impl<'a> FPT {

/// Two's complement of the sum of the bytes
pub fn header_checksum(&self) -> u8 {
let mut c = self.header.clone();
let mut c = self.header;
// Initial checksum field itself must be 0.
c.checksum = 0;
let d = [self.pre_header.as_bytes(), c.as_bytes()].concat();
Expand All @@ -373,12 +368,12 @@ impl<'a> FPT {
let f = e.flags;
retain(e.name(), options) && e.size() > 0 && f.kind() != PartitionKind::NVRAM
})
.map(|e| *e)
.copied()
.collect();
self.header.entries = self.entries.len() as u32;
// clear EFFS presence flag if applicable
if (!options.parts_force_retention.contains(&EFFS.into())
&& options.parts_force_deletion.len() == 0)
&& options.parts_force_deletion.is_empty())
|| options.parts_force_deletion.contains(&EFFS.into())
{
// TODO: define bitfield, parameterize via API
Expand Down
35 changes: 14 additions & 21 deletions src/part/gen2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,16 @@ pub struct DirPartition {
impl DirPartition {
pub fn check_signature(&self) -> Result<(), String> {
if self.dir.manifest.verify() {
return Ok(());
Ok(())
} else {
return Err("hash mismatch".into());
Err("hash mismatch".into())
}
}
}

#[derive(Serialize, Deserialize, Clone, Debug)]
pub enum Gen2Partition {
Dir(DirPartition),
Dir(Box<DirPartition>),
Data(DataPartition),
MalformedOrUnknown(UnknownOrMalformedPartition),
}
Expand Down Expand Up @@ -71,7 +71,8 @@ impl Gen2Partition {
let o = entry.offset();
let data = data.to_vec();
if let Ok(dir) = Directory::new(&data, o) {
Gen2Partition::Dir(DirPartition { dir, entry, data })
let p = DirPartition { dir, entry, data };
Gen2Partition::Dir(Box::new(p))
} else {
if debug {
let n = entry.name();
Expand All @@ -90,9 +91,7 @@ impl Gen2Partition {
// rebase Huffman chunks
let offset_diff = old_offset - offset;
println!("Adjust Huffman LUT, diff: {offset_diff:08x}");
if let Err(e) = p.dir.rebase_huffman_chunks(offset_diff) {
return Err(e);
}
p.dir.rebase_huffman_chunks(offset_diff)?;
if let Some((mod_offset, huffman_mod)) = p.dir.get_huffman_mod() {
let o = mod_offset;
let l = LUT_HEADER_SIZE;
Expand All @@ -110,8 +109,7 @@ impl Gen2Partition {
}

pub fn parse(fpt: &FPT, data: &[u8], debug: bool) -> Vec<Gen2Partition> {
let parts = fpt
.entries
fpt.entries
.iter()
.map(|e| {
let offset = e.offset();
Expand All @@ -131,13 +129,12 @@ pub fn parse(fpt: &FPT, data: &[u8], debug: bool) -> Vec<Gen2Partition> {
Gen2Partition::parse(&data[offset..end], *e, debug)
}
})
.collect();
parts
.collect()
}

pub fn clean(parts: &Vec<Gen2Partition>, options: &ClearOptions) -> Vec<Gen2Partition> {
pub fn clean(parts: &[Gen2Partition], options: &ClearOptions) -> Vec<Gen2Partition> {
use log::info;
let res = parts
parts
.iter()
.filter(|p| {
let e = p.entry();
Expand All @@ -158,16 +155,12 @@ pub fn clean(parts: &Vec<Gen2Partition>, options: &ClearOptions) -> Vec<Gen2Part
// TODO: Extend with user-provided list
let retention_list = strs_to_strings(ALWAYS_RETAIN);
let mut cleaned = p.data().clone();
match &p {
Gen2Partition::Dir(dir) => {
dir_clean(&dir.dir, &retention_list, &mut cleaned);
}
_ => {}
};
if let Gen2Partition::Dir(dir) = &p {
dir_clean(&dir.dir, &retention_list, &mut cleaned);
}
p.set_data(cleaned);
}
p
})
.collect();
res
.collect()
}
23 changes: 9 additions & 14 deletions src/part/gen3.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@ impl CPDPartition {
pub fn check_signature(&self) -> Result<(), String> {
if let Ok(m) = &self.cpd.manifest {
if m.verify() {
return Ok(());
Ok(())
} else {
return Err("hash mismatch".into());
Err("hash mismatch".into())
}
} else {
Err("no manifest found".into())
Expand Down Expand Up @@ -139,8 +139,7 @@ impl Gen3Partition {
}

pub fn parse(fpt: &FPT, data: &[u8], debug: bool) -> Vec<Gen3Partition> {
let parts = fpt
.entries
fpt.entries
.iter()
.map(|e| {
let offset = e.offset();
Expand All @@ -160,11 +159,10 @@ pub fn parse(fpt: &FPT, data: &[u8], debug: bool) -> Vec<Gen3Partition> {
Gen3Partition::parse(&data[offset..end], *e, debug)
}
})
.collect();
parts
.collect()
}

pub fn clean(parts: &Vec<Gen3Partition>, options: &ClearOptions) -> Vec<Gen3Partition> {
pub fn clean(parts: &[Gen3Partition], options: &ClearOptions) -> Vec<Gen3Partition> {
use log::info;
// Step 1: Reduce down to the partitions to be kept, i.e., non-removable
// ones.
Expand All @@ -181,7 +179,7 @@ pub fn clean(parts: &Vec<Gen3Partition>, options: &ClearOptions) -> Vec<Gen3Part
false
}
})
.map(|p| p.clone())
.cloned()
.collect::<Vec<Gen3Partition>>();
if options.keep_modules {
return reduced;
Expand All @@ -193,12 +191,9 @@ pub fn clean(parts: &Vec<Gen3Partition>, options: &ClearOptions) -> Vec<Gen3Part
// TODO: Extend with user-provided list
let retention_list = strs_to_strings(ALWAYS_RETAIN);
let mut cleaned = p.data().clone();
match &p {
Gen3Partition::Dir(dir) => {
dir_clean(&dir.cpd, &retention_list, &mut cleaned);
}
_ => {}
};
if let Gen3Partition::Dir(dir) = &p {
dir_clean(&dir.cpd, &retention_list, &mut cleaned);
}
p.set_data(cleaned);
}
// Step 3: Profit.
Expand Down
6 changes: 3 additions & 3 deletions src/part/part.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,14 +72,14 @@ pub struct ClearOptions {
pub fn retain(part_name: String, options: &ClearOptions) -> bool {
part_name == FTPR
|| options.parts_force_retention.contains(&part_name)
|| (options.parts_force_deletion.len() > 0
|| (!options.parts_force_deletion.is_empty()
&& !options.parts_force_deletion.contains(&part_name))
}

/// Clear out removable ranges in the FTPR directory
pub fn dir_clean(dir: &dyn Removables, retention_list: &Vec<String>, data: &mut Vec<u8>) {
pub fn dir_clean(dir: &dyn Removables, retention_list: &[String], data: &mut [u8]) {
use log::info;
for r in dir.removables(&retention_list) {
for r in dir.removables(retention_list) {
let offset = r.start;
let size = r.end - r.start;
info!("Freeing {size:8} bytes @ {offset:08x}");
Expand Down
Loading