Skip to content

Commit e4a3022

Browse files
committed
lib + dir: fix Clippy issues and rework parsing
- get rid of unwrap()s - add more bounds checks Signed-off-by: Daniel Maslowski <[email protected]>
1 parent e385fe4 commit e4a3022

File tree

3 files changed

+59
-44
lines changed

3 files changed

+59
-44
lines changed

src/dir/gen2.rs

Lines changed: 41 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ impl Entry {
105105
let b = self.mod_base;
106106
let rapi = self.flags.rapi();
107107
let kapi = self.flags.kapi();
108-
let code_start = (b as usize + (rapi + kapi) * 0x1000) as usize;
108+
let code_start = b as usize + (rapi + kapi) * 0x1000;
109109
let code_end = (b + self.code_size) as usize;
110110
let data_end = (b + self.memory_size) as usize;
111111
BinaryMap {
@@ -215,34 +215,33 @@ impl Display for Directory {
215215
}
216216
}
217217

218-
const HEADER_SIZE: usize = core::mem::size_of::<Header>();
219-
220218
impl Directory {
221219
pub fn new(data: &[u8], offset: usize) -> Result<Self, String> {
222-
let Ok(manifest) = Manifest::new(data) else {
223-
return Err("cannot parse Gen 2 directory manifest".to_string());
220+
let manifest = match Manifest::new(data) {
221+
Ok(r) => r,
222+
Err(e) => return Err(format!("cannot parse Gen 2 directory manifest: {e:?}")),
224223
};
225-
let Ok((header, _)) = Header::read_from_prefix(&manifest.mdata) else {
226-
return Err("cannot parse ME FW Gen 2 directory header".to_string());
224+
let (header, rest) = match Header::read_from_prefix(&manifest.mdata) {
225+
Ok((h, rest)) => (h, rest),
226+
Err(e) => return Err(format!("cannot parse Gen 2 directory header: {e:?}")),
227227
};
228228
let name = match from_utf8(&header.name) {
229229
Ok(n) => n.trim_end_matches('\0').to_string(),
230230
Err(_) => format!("{:02x?}", header.name),
231231
};
232232

233233
// Check magic bytes of first entry.
234-
let pos = HEADER_SIZE;
235-
let slice = &manifest.mdata[pos..];
236-
let m = &slice[..4];
234+
let m = &rest[..4];
237235
if !m.eq(MODULE_MAGIC_BYTES) {
238236
return Err(format!(
239237
"entry magic not found, got {m:02x?}, wanted {MODULE_MAGIC_BYTES:02x?} ({MODULE_MAGIC})"
240238
));
241239
}
242240
// Parse the entries themselves.
243241
let count = manifest.header.entries as usize;
244-
let Ok((r, _)) = Ref::<_, [Entry]>::from_prefix_with_elems(slice, count) else {
245-
return Err(format!("cannot parse ME FW Gen 2 directory entries",));
242+
let r = match Ref::<_, [Entry]>::from_prefix_with_elems(rest, count) {
243+
Ok((r, _)) => r,
244+
Err(e) => return Err(format!("cannot parse Gen 2 directory entries: {e}")),
246245
};
247246
let entries = r.to_vec();
248247

@@ -265,16 +264,28 @@ impl Directory {
265264
"Expected {SIG_LUT_BYTES:02x?} @ {o:08x}, got {sig:02x?}"
266265
)));
267266
}
268-
let (header, _) = LutHeader::read_from_prefix(&data[o..]).unwrap();
267+
let header = match LutHeader::read_from_prefix(&data[o..]) {
268+
Ok((r, _)) => r,
269+
Err(e) => return Module::Huffman(Err(format!("{e:?}"))),
270+
};
269271
let count = header.chunk_count as usize;
270272
let lo = o + LUT_HEADER_SIZE;
271-
let (lut, _) =
272-
Ref::<_, [u32]>::from_prefix_with_elems(&data[lo..], count).unwrap();
273-
let huff = HuffmanModule {
274-
header,
275-
chunks: lut.to_vec(),
276-
};
277-
Module::Huffman(Ok((*e, huff)))
273+
let l = data.len();
274+
if lo > l {
275+
return Module::Huffman(Err(format!(
276+
"offset {lo:08x} out of bounds ({l})"
277+
)));
278+
}
279+
match Ref::<_, [u32]>::from_prefix_with_elems(&data[lo..], count) {
280+
Ok((lut, _)) => {
281+
let huff = HuffmanModule {
282+
header,
283+
chunks: lut.to_vec(),
284+
};
285+
Module::Huffman(Ok((*e, huff)))
286+
}
287+
Err(e) => Module::Huffman(Err(format!("{e}"))),
288+
}
278289
}
279290
Compression::Lzma => {
280291
if sig != SIG_LZMA_BYTES {
@@ -319,7 +330,7 @@ impl Directory {
319330
Err("new offset cannot be calculated".into())
320331
}
321332

322-
fn dump_ranges(ranges: &Vec<Range<usize>>) {
333+
fn dump_ranges(ranges: &[Range<usize>]) {
323334
let group_size = 4;
324335
for (i, r) in ranges.iter().enumerate() {
325336
if i % group_size == group_size - 1 {
@@ -332,7 +343,7 @@ impl Directory {
332343
}
333344

334345
/// Get the offset ranges of the chunks.
335-
fn chunks_as_ranges(&self, chunks: &Vec<u32>, stream_end: usize) -> Vec<Range<usize>> {
346+
fn chunks_as_ranges(&self, chunks: &[u32], stream_end: usize) -> Vec<Range<usize>> {
336347
// NOTE: This is the end of the directory.
337348
// me_cleaner uses the end of the ME region.
338349
let dir_end = self.offset + self.size;
@@ -352,6 +363,7 @@ impl Directory {
352363
}
353364
})
354365
.collect::<Vec<usize>>();
366+
// This should move dir_end to the end.
355367
nonzero_offsets.sort();
356368
// Turn offsets into ranges by finding the offset of the next chunk.
357369
offsets
@@ -360,9 +372,11 @@ impl Directory {
360372
let o = *offset;
361373
let e = if o != 0 {
362374
// NOTE: nonzero_offsets are a subset of offsets, so this should never fail.
375+
#[allow(clippy::unwrap_used)]
363376
let p = nonzero_offsets.iter().position(|e| *e == o).unwrap();
364377
let next = p + 1;
365-
// The last entry has no successor.
378+
// The last entry potentially has no successor. It would be
379+
// dir_end, which is the initial entry in nonzero_offsets.
366380
if next < nonzero_offsets.len() {
367381
nonzero_offsets[next]
368382
} else {
@@ -395,7 +409,7 @@ impl Directory {
395409
if (*c >> 24) as u8 == CHUNK_INACTIVE {
396410
//
397411
} else {
398-
*c = *c - offset_diff;
412+
*c -= offset_diff;
399413
};
400414
}
401415
return Ok(());
@@ -415,15 +429,15 @@ impl Directory {
415429
.find(|m| matches!(m, Module::Huffman(Ok(_))))
416430
{
417431
let lut_header_offset = e.offset as usize;
418-
return Some((lut_header_offset, &h));
432+
return Some((lut_header_offset, h));
419433
}
420434
None
421435
}
422436
}
423437

424438
impl Removables for Directory {
425439
/// Removable ranges relative to the start of the Directory
426-
fn removables(&self, retention_list: &Vec<String>) -> Vec<Range<usize>> {
440+
fn removables(&self, retention_list: &[String]) -> Vec<Range<usize>> {
427441
use log::{debug, info, warn};
428442
let debug = false;
429443
let mut removables = vec![];
@@ -445,7 +459,7 @@ impl Removables for Directory {
445459
// NOTE: The header is always the same, since multiple
446460
// Huffman-encoded modules point to the same offset.
447461
let cs = h.header.chunk_size;
448-
if all_chunks.len() == 0 {
462+
if all_chunks.is_empty() {
449463
info!("Huffman chunk size: {cs}");
450464
let stream_end = (h.header.hs0 + h.header.hs1) as usize;
451465
all_chunks = self.chunks_as_ranges(&h.chunks, stream_end);

src/dir/gen3.rs

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -135,21 +135,21 @@ impl Display for CodePartitionDirectory {
135135
};
136136
format!("{m}\n{kh}{me}")
137137
}
138-
Err(e) => format!("{e}"),
138+
Err(e) => e.to_string(),
139139
};
140-
let l3 = format!(" file name offset end size kind");
141-
write!(f, "{l1}\n{l2}\n{l3}\n").unwrap();
140+
let l3 = " file name offset end size kind".to_string();
141+
write!(f, "{l1}\n{l2}\n{l3}\n")?;
142142
let sorted_entries = self.sorted_entries();
143143
for e in sorted_entries {
144-
write!(f, " {e}\n").unwrap();
144+
writeln!(f, " {e}")?;
145145
}
146146
write!(f, "")
147147
}
148148
}
149149

150150
impl CodePartitionDirectory {
151151
pub fn new(data: &[u8], offset: usize) -> Result<Self, String> {
152-
let Ok((header, _)) = CPDHeader::read_from_prefix(&data) else {
152+
let Ok((header, _)) = CPDHeader::read_from_prefix(data) else {
153153
return Err("could not parse CPD header".to_string());
154154
};
155155
let name = header.name();
@@ -203,7 +203,7 @@ impl CodePartitionDirectory {
203203

204204
impl Removables for CodePartitionDirectory {
205205
/// Removable ranges relative to the start of the directory
206-
fn removables(&self, retention_list: &Vec<String>) -> Vec<Range<usize>> {
206+
fn removables(&self, retention_list: &[String]) -> Vec<Range<usize>> {
207207
use log::info;
208208
let mut removables = vec![];
209209

@@ -224,12 +224,13 @@ impl Removables for CodePartitionDirectory {
224224
}
225225
// Remaining space to free after last entry
226226
let sorted = self.sorted_entries();
227-
let last = sorted.last().unwrap();
228-
let end = (last.flags_and_offset.offset() + last.size) as usize;
229-
let o = end.next_multiple_of(FOUR_K);
230-
let e = self.size;
231-
removables.push(o..e);
232-
info!("Remaining space: {o:08x}..{e:08x}");
227+
if let Some(last) = sorted.last() {
228+
let end = (last.flags_and_offset.offset() + last.size) as usize;
229+
let o = end.next_multiple_of(FOUR_K);
230+
let e = self.size;
231+
removables.push(o..e);
232+
info!("Remaining space: {o:08x}..{e:08x}");
233+
}
233234
removables
234235
}
235236
}

src/lib.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ pub const EMPTY: u8 = 0xff;
2222
pub trait Removables {
2323
/// Get removable ranges relative to the start of a section or directory.
2424
/// The respective section/directory needs to know its own offset.
25-
fn removables(&self, retention_list: &Vec<String>) -> Vec<core::ops::Range<usize>>;
25+
fn removables(&self, retention_list: &[String]) -> Vec<core::ops::Range<usize>>;
2626
}
2727

2828
#[derive(Serialize, Deserialize, Clone, Debug)]
@@ -34,7 +34,7 @@ pub struct Firmware {
3434

3535
impl Firmware {
3636
pub fn parse(data: &[u8], debug: bool) -> Self {
37-
let ifd = IFD::parse(&data);
37+
let ifd = IFD::parse(data);
3838
let me = match &ifd {
3939
Ok(ifd) => {
4040
let me_region = ifd.regions.me_range();
@@ -52,9 +52,9 @@ impl Firmware {
5252
}
5353

5454
pub fn scan(data: &[u8], debug: bool) -> Self {
55-
let ifd = IFD::parse(&data);
56-
let me = ME::scan(&data, debug);
57-
let fit = Fit::new(&data);
55+
let ifd = IFD::parse(data);
56+
let me = ME::scan(data, debug);
57+
let fit = Fit::new(data);
5858
Self { ifd, me, fit }
5959
}
6060
}

0 commit comments

Comments
 (0)