Skip to content

Commit d1f4ecf

Browse files
qkaisere3krisztian
authored andcommitted
fix(filesystem.romfs): improve end offset calculation.
1 parent bb09266 commit d1f4ecf

File tree

1 file changed

+15
-12
lines changed

1 file changed

+15
-12
lines changed

Diff for: unblob/handlers/filesystem/romfs.py

+15-12
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
from unblob.extractor import is_safe_path
1212

13-
from ...file_utils import Endian, InvalidInputFormat, read_until_past, round_up
13+
from ...file_utils import Endian, InvalidInputFormat, round_up
1414
from ...models import Extractor, File, HexString, StructHandler, ValidChunk
1515

1616
logger = get_logger()
@@ -25,6 +25,7 @@
2525
WORLD_RWX = 0o777
2626
ROMFS_HEADER_SIZE = 512
2727
ROMFS_SIGNATURE = b"-rom1fs-"
28+
PADDING_ALIGNMENT = 1024
2829

2930

3031
@unique
@@ -361,29 +362,31 @@ class RomFSFSHandler(StructHandler):
361362

362363
def calculate_chunk(self, file: File, start_offset: int) -> Optional[ValidChunk]:
363364

364-
if not valid_checksum(file.read(512)):
365+
checksum = file.read(512)
366+
if not valid_checksum(checksum):
365367
raise InvalidInputFormat("Invalid RomFS checksum.")
366368

367-
file.seek(-512, io.SEEK_CUR)
369+
file.seek(-len(checksum), io.SEEK_CUR)
368370

369371
# Every multi byte value must be in big endian order.
370372
header = self.parse_header(file, Endian.BIG)
371373

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-
379374
# Another thing to note is that romfs works on file headers and data
380375
# aligned to 16 byte boundaries, but most hardware devices and the block
381376
# device drivers are unable to cope with smaller than block-sized data.
382377
# To overcome this limitation, the whole size of the file system must be
383378
# 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.")
385388

386389
return ValidChunk(
387390
start_offset=start_offset,
388-
end_offset=file.tell(),
391+
end_offset=end_offset,
389392
)

0 commit comments

Comments
 (0)