studio/install: strip top-level dir from repaired symlink target (#5467)

The repair in 5465 returned the full archive entry name (e.g.
"llama-b9165 libggml-rpc.0.11.1.dylib") but safe_link_target joins
the return value with target.parent (which already lives under
base llama-b9165). That doubled the prefix to
base llama-b9165 llama-b9165 libggml-rpc.0.11.1.dylib, the
resolved path never existed, and extract_tar_safely still raised
'tar archive contained unresolved link entries'.

Strip the top-level dir before returning so the linkname is
relative to target.parent, mirroring how unmangled symlinks are
stored in the tar (basename-only relative to the symlink).

Verified end-to-end against the upstream b9165 tarball: extraction
succeeds and every symlink resolves to an existing file.
This commit is contained in:
Daniel Han 2026-05-15 15:09:50 -07:00 committed by GitHub
commit 2de99a23d8
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -3447,7 +3447,11 @@ def extract_archive(archive_path: Path, destination: Path) -> None:
(linkname starts with the top-level dir name but no following
slash) and search archive entries under that dir for a real
file whose basename ends with the mangled suffix. Only accept
when the suffix uniquely identifies a real archive entry."""
when the suffix uniquely identifies a real archive entry.
Returns the corrected linkname expressed relative to the
member's parent directory -- callers join it with
`target.parent`, so a full `top/file` path would double the
prefix into `top/top/file`."""
if "/" not in member_name or "/" in link_name:
return None
top, _, _ = member_name.partition("/")
@ -3466,7 +3470,10 @@ def extract_archive(archive_path: Path, destination: Path) -> None:
]
if len(candidates) != 1:
return None
return candidates[0]
# Strip the top-level dir so the caller's `target.parent / Path(...)`
# composition resolves inside the staging dir, not into a duplicate
# `top/top/...` path.
return candidates[0][len(prefix) :]
def safe_link_target(
base: Path,