Stop rewriting an alias file's own metadata
Writing a volume rebuilds every alias file, because the `alis` record names its target by CNID and CNIDs are assigned afresh on each write. It rebuilt more than the record, though: the file's type and creator were overwritten with ones guessed from the target, the rest of the resource fork was thrown away, and the data fork was cleared. Round-tripping the Apple Menu's Control Panels alias out of a System 7 image therefore turned `fact` into `fdrp`, dropped its `vers` resources, and renamed the `alis` from "Control Panels alias" to "Control Panels". Aliases to applications lost their `adrp` for whatever the target's type happened to be -- `APPC`, `cdev`. Only the `alis` resource is replaced now, in place and under its own name; type and creator are guessed only for an alias built here, which has neither. Reading and rewriting the 29 infinite-mac images machfs can parse touches 73 alias files: type and creator used to change on 10 of them and now change on none, and 28 resource forks used to lose more than the `alis` record and now lose nothing else. (Their data forks were already empty, so clearing those had cost nothing in practice.) For mihaip/infinite-mac#84
This commit is contained in:
1 parent
1f8e7b5288
commit
d32a327c5f
2 files changed
+69
-16
No files matched your search
+34
@@ -1,5 +1,7 @@
|
||||
from machfs import *
|
||||
from machfs import bitmanip, btree
|
||||
from machfs.main import FinderFlags
|
||||
from macresources import Resource, make_file, parse_file
|
||||
import os
|
||||
import struct
|
||||
import time
|
||||
@@ -27,6 +29,38 @@ def test_roundtrip():
|
||||
assert f.data in copies[-1]
|
||||
|
||||
|
||||
def test_alias_keeps_what_belongs_to_the_file():
|
||||
h = Volume()
|
||||
h.name = 'AliasTest'
|
||||
|
||||
target = File()
|
||||
target.type, target.creator = b'APPC', b'wnkl'
|
||||
target.data = b'target data'
|
||||
h['target'] = target
|
||||
|
||||
# Neither 'fact' nor the 'vers' resource can be derived from the target.
|
||||
vers = Resource(b'vers', 2, data=b'\x01\x00\x80\x00\x00\x00\x041.0')
|
||||
stale = Resource(b'alis', 0, name='alias resource name', data=bytes(150))
|
||||
alias = File()
|
||||
alias.flags |= FinderFlags.kIsAlias
|
||||
alias.type, alias.creator = b'fact', b'MACS'
|
||||
alias.rsrc = make_file([stale, vers])
|
||||
alias.aliastarget = target
|
||||
h['the alias'] = alias
|
||||
|
||||
copy = Volume()
|
||||
copy.read(h.write(10*1024*1024, desktopdb=False, bootable=False))
|
||||
got = copy['the alias']
|
||||
|
||||
assert (got.type, got.creator) == (b'fact', b'MACS')
|
||||
|
||||
resources = {(r.type, r.id): r for r in parse_file(got.rsrc)}
|
||||
assert resources[b'vers', 2].data == vers.data
|
||||
assert resources[b'alis', 0].name == 'alias resource name'
|
||||
# The record itself holds this volume's CNIDs, so it is rebuilt.
|
||||
assert resources[b'alis', 0].data != stale.data
|
||||
|
||||
|
||||
def test_open_folder():
|
||||
h = Volume()
|
||||
h.name = 'OpenFolderTest'
|
||||
|
||||
Reference in new issue
Block a user