Read extents overflow file

This commit is contained in:
Elliot Nunn 2018-10-08 09:33:34 +08:00
parent e3d3623de9
commit eb847a97cd
2 changed files with 19 additions and 15 deletions

View File

@ -125,8 +125,12 @@ class Volume(directory.AbstractFolder):
extoflow = {} extoflow = {}
for rec in btree.dump_btree(extrec2bytes(drXTExtRec)): for rec in btree.dump_btree(extrec2bytes(drXTExtRec)):
if rec[0] != 7: continue if rec[0] != 7: continue
# print(key, val) xkrFkType, xkrFNum, xkrFABN, extrec = struct.unpack_from('>xBLH12s', rec)
pass if xkrFkType == 0xFF:
fork = 'rsrc'
elif xkrFkType == 0:
fork = 'data'
extoflow[xkrFNum, fork, xkrFABN] = extrec
cnids = {} cnids = {}
childlist = [] # list of (parent_cnid, child_name, child_object) tuples 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) 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)]: for fork, length, extrec in [('data', filLgLen, filExtRec), ('rsrc', filRLgLen, filRExtRec)]:
accum = bytearray() accum = bytearray(extrec2bytes(extrec))
extrec = list(struct.unpack('>HHHHHH', extrec)) while len(accum) < length:
extrec = list(zip(extrec[::2], extrec[1::2])) next_blk = len(accum) // drAlBlkSiz
for extstart, extlength in extrec: next_extrec = extoflow[filFlNum, fork, next_blk]
if extlength == 0: continue accum.extend(extrec2bytes(next_extrec))
astart = 512*drAlBlSt + drAlBlkSiz*extstart
astop = astart + drAlBlkSiz*extlength
accum.extend(from_volume[astart:astop])
del accum[length:] # logical length can be less than a number of blocks 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) setattr(f, fork, accum)

View File

@ -51,6 +51,11 @@ def test_macos_mount():
os.system('umount /Volumes/ElmoTest') os.system('umount /Volumes/ElmoTest')
assert recovered == hf.data assert recovered == hf.data
# h2 = Volume() h2 = Volume()
# h2.read(ser) h2.read(ser)
# assert h2['testfile-000'].data == hf.data 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