From 8748315722cc6cd04675953af92e1f8e700c8e1b Mon Sep 17 00:00:00 2001 From: Eric Smith Date: Wed, 11 Apr 2018 23:49:29 -0600 Subject: [PATCH] Better filename validation. Decode creation dates. --- sosdisk.py | 37 ++++++++++++++++++++++++++++++------- 1 file changed, 30 insertions(+), 7 deletions(-) diff --git a/sosdisk.py b/sosdisk.py index 6ddbdd3..32ea068 100644 --- a/sosdisk.py +++ b/sosdisk.py @@ -1,3 +1,4 @@ +import datetime import string import struct import sys @@ -46,11 +47,30 @@ interleave_tables = { 'dos': dos_to_phys_sect, sos_valid_fn_chars = set(string.ascii_uppercase + string.digits + '.') -def bytes_to_sos_filename(b): +def bytes_to_sos_filename(l, b): + assert len(b) == 15 + assert 1 <= l <= 15 s = str(b, 'ascii') - assert all(c in sos_valid_fn_chars for c in s) + assert all(c in sos_valid_fn_chars for c in s[:l]) + assert all(c == 0 for c in b[l:]) return s.lower() +def u32_to_sos_timestamp(b): + if b == 0: + return None + ymd = b & 0xffff + hm = b >> 16 + year = 1900 + (ymd >> 9) + month = (ymd >> 5) & 0xf + day = ymd & 0x1f + hour = hm >> 8 + minute = hm & 0xff + assert 1 <= month <= 12 + assert 1 <= day <= 31 + assert 0 <= hour <= 23 + assert 0 <= minute <= 59 + return datetime.datetime(year, month, day, hour, minute) + class SOSDirectoryEntry: def __init__(self, disk): @@ -64,15 +84,17 @@ class SOSVolumeDirectoryHeader(SOSDirectoryEntry): def __init__(self, disk, entry_data): super().__init__(disk) #print('volume directory header') - (self.storage, self.filename, self.reserved, self.creation, self.version, self.min_version, self.access, self.entry_length, self.entries_per_block, self.file_count, self.bitmap_pointer, self.total_blocks) = struct.unpack('>= 4 + self.name = bytes_to_sos_filename(name_length, name_b) assert self.storage == 0xf assert self.version == 0 assert self.min_version == 0 assert self.entry_length == 0x27 assert self.entries_per_block == 0x0d assert self.total_blocks == disk.block_count + self.creation = u32_to_sos_timestamp(creation_b) class SOSSubdirectoryHeader(SOSDirectoryEntry): def __init__(self, disk, entry_data): @@ -82,19 +104,20 @@ class SOSSubdirectoryHeader(SOSDirectoryEntry): class SOSFileEntry(SOSDirectoryEntry): def __init__(self, disk, entry_data): super().__init__(disk) - (self.storage, self.filename, self.file_type, self.key_pointer, self.blocks_used, self.eof, self.creation, self.version, self.min_version, self.access, self.aux_type, self.last_mod, self.header_pointer) = struct.unpack('>= 4 if self.storage == 0: return - self.name = bytes_to_sos_filename(entry_data[1:1+name_length]) + self.name = bytes_to_sos_filename(name_length, name_b) + self.creation = u32_to_sos_timestamp(creation_b) if (self.storage == 0xd): self.subdir = SOSDirectory(disk, self.key_pointer) def print(self, prefix, file): if self.storage == 0: return - print('%s/%s, storage type %x' % (prefix, self.name, self.storage), file = file) + print('%s/%s, storage type %x, %s' % (prefix, self.name, self.storage, self.creation), file = file) if (self.storage == 0xd): self.subdir.print(prefix + '/' + self.name, file)