From eb847a97cd49d8ec68819478c07b5f5bc6f5ac28 Mon Sep 17 00:00:00 2001 From: Elliot Nunn Date: Mon, 8 Oct 2018 09:33:34 +0800 Subject: [PATCH] Read extents overflow file --- machfs/main.py | 23 +++++++++++------------ test_all.py | 11 ++++++++--- 2 files changed, 19 insertions(+), 15 deletions(-) diff --git a/machfs/main.py b/machfs/main.py index 9bd87df..8b30443 100644 --- a/machfs/main.py +++ b/machfs/main.py @@ -125,8 +125,12 @@ class Volume(directory.AbstractFolder): extoflow = {} for rec in btree.dump_btree(extrec2bytes(drXTExtRec)): if rec[0] != 7: continue - # print(key, val) - pass + xkrFkType, xkrFNum, xkrFABN, extrec = struct.unpack_from('>xBLH12s', rec) + if xkrFkType == 0xFF: + fork = 'rsrc' + elif xkrFkType == 0: + fork = 'data' + extoflow[xkrFNum, fork, xkrFABN] = extrec cnids = {} childlist = [] # list of (parent_cnid, child_name, child_object) tuples @@ -176,17 +180,12 @@ class Volume(directory.AbstractFolder): f.type, f.creator, f.flags, f.x, f.y = struct.unpack_from('>4s4sHHH', filUsrWds) for fork, length, extrec in [('data', filLgLen, filExtRec), ('rsrc', filRLgLen, filRExtRec)]: - accum = bytearray() - extrec = list(struct.unpack('>HHHHHH', extrec)) - extrec = list(zip(extrec[::2], extrec[1::2])) - for extstart, extlength in extrec: - if extlength == 0: continue - astart = 512*drAlBlSt + drAlBlkSiz*extstart - astop = astart + drAlBlkSiz*extlength - accum.extend(from_volume[astart:astop]) + accum = bytearray(extrec2bytes(extrec)) + while len(accum) < length: + next_blk = len(accum) // drAlBlkSiz + next_extrec = extoflow[filFlNum, fork, next_blk] + accum.extend(extrec2bytes(next_extrec)) del accum[length:] # logical length can be less than a number of blocks - if len(accum) != length: - raise ValueError('need to consult extents overflow file') setattr(f, fork, accum) diff --git a/test_all.py b/test_all.py index 73f85c6..7bc3816 100644 --- a/test_all.py +++ b/test_all.py @@ -51,6 +51,11 @@ def test_macos_mount(): os.system('umount /Volumes/ElmoTest') assert recovered == hf.data - # h2 = Volume() - # h2.read(ser) - # assert h2['testfile-000'].data == hf.data + h2 = Volume() + h2.read(ser) + assert h2['testfile-000'].data == hf.data + +def test_extents_overflow(): + h = Volume() + h.read(open('SourceForEmulator.dmg','rb').read()) + assert h['aa'].data == b'a' * 278528