fix(engines): a source tarball with a link in it still extracts

The stdlib data filter raises on a link to an absolute path, and the
pinned Matcha-TTS tarball ships one (data -> its author's training
folder), which aborted the fetch and with it the CosyVoice install. Found
by building the real environment. Links are now skipped on every
interpreter, as the pre-3.11.4 path already did.
This commit is contained in:
Palash Debnath
2026-09-10 11:34:03 -07:00
parent 399b9ec3f6
commit efdec50081
2 changed files with 50 additions and 2 deletions
+17 -2
View File
@@ -1273,8 +1273,8 @@ def _download_and_extract(job: dict, url: str, dest: Path, work_root: Path, env_
with tempfile.TemporaryDirectory(dir=str(root)) as tmp_dir:
with tarfile.open(tmp_tar, "r:gz") as tf:
try:
tf.extractall(tmp_dir, filter="data") # stdlib safe-extract (3.11.4+)
except TypeError: # pragma: no cover — pre-filter= interpreters
tf.extractall(tmp_dir, filter=_no_links_data_filter) # 3.11.4+
except (TypeError, AttributeError): # pragma: no cover — no filter= / data_filter
_safe_extract_members(tf, tmp_dir)
entries = [p for p in Path(tmp_dir).iterdir() if p.is_dir()]
if len(entries) != 1:
@@ -1345,6 +1345,21 @@ def _run_post_install(spec: SidecarSpec, job: dict, py: Path, checkout: Path) ->
)
def _no_links_data_filter(member: "tarfile.TarInfo", path: str):
"""The stdlib "data" filter, except that links are skipped, not fatal.
The "data" filter raises on a link to an absolute path, and the pinned
Matcha-TTS tarball (a CosyVoice submodule) ships one: ``data`` points at
its author's own training-data folder. That aborted the whole fetch. No
installer here uses a link from a source tree, symlinks need privileges
on Windows, and the pre-3.11.4 path below already drops them, so both
paths now behave the same.
"""
if member.issym() or member.islnk():
return None
return tarfile.data_filter(member, path)
def _safe_extract_members(tf: "tarfile.TarFile", dest: str) -> None:
"""Tar-slip-guarded extraction for interpreters without
``extractall(filter="data")`` (Python < 3.11.4).
+33
View File
@@ -1455,3 +1455,36 @@ def test_cosyvoice_post_install_code_compiles_for_any_checkout_path():
spec = si.get_spec("cosyvoice")
compile(si._expand(spec.post_install_code, Path("C:/Program Files/x y/CosyVoice")),
"<post-install>", "exec")
def _tarball_with_absolute_symlink() -> bytes:
"""Shaped like the pinned Matcha-TTS tarball: a package plus a `data` link
to a folder on its author's machine."""
buf = io.BytesIO()
with tarfile.open(fileobj=buf, mode="w:gz") as tf:
data = b"x = 1\n"
info = tarfile.TarInfo("Matcha-abc/matcha/__init__.py")
info.size = len(data)
tf.addfile(info, io.BytesIO(data))
link = tarfile.TarInfo("Matcha-abc/data")
link.type = tarfile.SYMTYPE
link.linkname = "/home/someone/Projects/Grad-TTS/data"
tf.addfile(link)
return buf.getvalue()
def test_a_tarball_with_an_absolute_link_still_extracts(monkeypatch, tmp_path):
"""The stdlib "data" filter raises AbsoluteLinkError on such a link, which
aborted the Matcha-TTS fetch and with it the CosyVoice install."""
import httpx
monkeypatch.setattr(httpx, "stream", lambda method, url, **kw: _FakeStream(_tarball_with_absolute_symlink()))
dest = tmp_path / "third_party" / "Matcha-TTS"
dest.parent.mkdir(parents=True)
job = si._new_job("fake-side")
si._download_and_extract(job, "https://example.test/m.tar.gz", dest, tmp_path, "OMNIVOICE_FAKE_SIDE_DIR")
assert (dest / "matcha" / "__init__.py").is_file()
assert not (dest / "data").exists() and not (dest / "data").is_symlink()