fix: ignore MSYS mount-table symlink in bundled Git archive

This commit is contained in:
ethernet
2026-09-24 02:35:42 -04:00
parent 01e6e89ca2
commit f17e27b1ce
2 changed files with 35 additions and 5 deletions

View File

@@ -160,8 +160,8 @@ def _tar_filter(member, dest: str):
def extract_tar(archive: Path, dest: Path, *, git_msys: bool = False) -> None:
"""Extract a tarball with one containment policy for PM's tar consumers.
MSYS Git ships dev/fd links into /proc; those aren't usable on Windows.
Skip only those known links, never a filter error or failed file write.
MSYS Git ships dev/fd links and etc/mtab into /proc; those aren't usable
on Windows. Skip only those known links, never a filter error or failed file write.
"""
import tarfile
@@ -169,9 +169,10 @@ def extract_tar(archive: Path, dest: Path, *, git_msys: bool = False) -> None:
real_dest = os.path.realpath(dest)
with tarfile.open(archive) as tf:
if git_msys:
members = (m for m in tf if not (
m.issym() and m.name.lstrip("./").startswith("dev/")
and m.linkname.startswith("/proc/")))
members = (m for m in tf if not (m.issym() and (
(m.name.lstrip("./").startswith("dev/") and m.linkname.startswith("/proc/"))
or (m.name == "etc/mtab" and m.linkname == "/proc/mounts")
)))
for member in members:
tf.extract(member, dest, filter=lambda item, path: _tar_filter(item, real_dest))
else:

View File

@@ -42,6 +42,35 @@ def test_symlinks_escaping_the_destination_are_rejected(tmp_path, linkname):
extract(archive, tmp_path / "out")
assert not (tmp_path / "out" / "python/bin/evil").is_symlink()
def test_git_tar_ignores_msys_mount_table_link(tmp_path):
from pm.packages import Git
archive = tmp_path / "git.tar.bz2"
with tarfile.open(archive, "w:bz2") as tf:
mtab = tarfile.TarInfo("etc/mtab")
mtab.type, mtab.linkname = tarfile.SYMTYPE, "/proc/mounts"
tf.addfile(mtab)
binary = tarfile.TarInfo("cmd/git.exe")
binary.size = 1
tf.addfile(binary, io.BytesIO(b"x"))
dest = tmp_path / "out"
Git().unpack(archive, dest, "win32-x64")
assert (dest / "cmd/git.exe").read_bytes() == b"x"
assert not (dest / "etc/mtab").is_symlink()
def test_git_tar_rejects_unrelated_mount_table_links(tmp_path):
from pm.packages import Git
archive = tmp_path / "git.tar.bz2"
with tarfile.open(archive, "w:bz2") as tf:
mtab = tarfile.TarInfo("etc/mtab")
mtab.type, mtab.linkname = tarfile.SYMTYPE, "/etc/passwd"
tf.addfile(mtab)
with pytest.raises(tarfile.FilterError):
Git().unpack(archive, tmp_path / "out", "win32-x64")
def test_git_tar_skips_only_msys_proc_links_and_rejects_other_unsafe_entries(tmp_path):
from pm.packages import Git