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:
dualfroz committed 2026-09-13 15:20:49 +02:00
1 parent 1f8e7b5288
commit d32a327c5f
2 files changed
+69 -16

No files matched your search

+34
View File
@@ -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'