|
10 | 10 |
|
11 | 11 | from unblob.extractor import is_safe_path |
12 | 12 |
|
13 | | -from ...file_utils import Endian, InvalidInputFormat, read_until_past, round_up |
| 13 | +from ...file_utils import Endian, InvalidInputFormat, round_up |
14 | 14 | from ...models import Extractor, File, HexString, StructHandler, ValidChunk |
15 | 15 |
|
16 | 16 | logger = get_logger() |
|
25 | 25 | WORLD_RWX = 0o777 |
26 | 26 | ROMFS_HEADER_SIZE = 512 |
27 | 27 | ROMFS_SIGNATURE = b"-rom1fs-" |
| 28 | +PADDING_ALIGNMENT = 1024 |
28 | 29 |
|
29 | 30 |
|
30 | 31 | @unique |
@@ -361,29 +362,31 @@ class RomFSFSHandler(StructHandler): |
361 | 362 |
|
362 | 363 | def calculate_chunk(self, file: File, start_offset: int) -> Optional[ValidChunk]: |
363 | 364 |
|
364 | | - if not valid_checksum(file.read(512)): |
| 365 | + checksum = file.read(512) |
| 366 | + if not valid_checksum(checksum): |
365 | 367 | raise InvalidInputFormat("Invalid RomFS checksum.") |
366 | 368 |
|
367 | | - file.seek(-512, io.SEEK_CUR) |
| 369 | + file.seek(-len(checksum), io.SEEK_CUR) |
368 | 370 |
|
369 | 371 | # Every multi byte value must be in big endian order. |
370 | 372 | header = self.parse_header(file, Endian.BIG) |
371 | 373 |
|
372 | | - # The zero terminated name of the volume, padded to 16 byte boundary. |
373 | | - get_string(file) |
374 | | - |
375 | | - # seek filesystem size (number of accessible bytes in this fs) |
376 | | - # from the actual end of the header |
377 | | - file.seek(header.full_size, io.SEEK_CUR) |
378 | | - |
379 | 374 | # Another thing to note is that romfs works on file headers and data |
380 | 375 | # aligned to 16 byte boundaries, but most hardware devices and the block |
381 | 376 | # device drivers are unable to cope with smaller than block-sized data. |
382 | 377 | # To overcome this limitation, the whole size of the file system must be |
383 | 378 | # padded to an 1024 byte boundary. |
384 | | - read_until_past(file, b"\x00") |
| 379 | + end_offset = start_offset + round_up( |
| 380 | + len(header) + header.full_size, PADDING_ALIGNMENT |
| 381 | + ) |
| 382 | + fs_size = len(header) + header.full_size |
| 383 | + padding_size = round_up(fs_size, PADDING_ALIGNMENT) - fs_size |
| 384 | + if padding_size: |
| 385 | + file.seek(start_offset + fs_size, io.SEEK_SET) |
| 386 | + if file.read(padding_size) != bytes([0]) * padding_size: |
| 387 | + raise InvalidInputFormat("Invalid padding.") |
385 | 388 |
|
386 | 389 | return ValidChunk( |
387 | 390 | start_offset=start_offset, |
388 | | - end_offset=file.tell(), |
| 391 | + end_offset=end_offset, |
389 | 392 | ) |
0 commit comments