Repository navigation
Description
Malformed installpkg artifact raises an internal error.
Affected code
``VenvCmdBuilder.extract_install_info() in src/tox/tox_env/python/virtual_env/package/cmd_builder.py at report commit 7988418936b730b19981ba934dc8b57186d6b957.
Mechanism
VenvCmdBuilder.extract_install_info parses the selected artifact without handling its parse errors. A malformed artifact propagates an internal exception.
Reproduction
The reproducer returned BUG at the report commit and at main commit d1963d076c78ed4c03c6f8c6e8fbaf9163e21f48 in a disposable container without network access.
Save the Dockerfile below in the finding directory. Build the source image from main commit d1963d076c78ed4c03c6f8c6e8fbaf9163e21f48, then run:
main_checkout=/path/to/tox-main
docker build -f Dockerfile.repro -t tox-sec-head "$main_checkout"
docker run --rm --network=none -u 0 -w /src -v "$PWD/repro:/tmp/repro:ro,z" -v "$PWD/repro.d:/tmp/repro.d:ro,z" tox-sec-head /tmp/reproa: internal error
File "/src/src/tox/tox_env/python/virtual_env/package/cmd_builder.py", line 117, in extract_install_info
tarfile.ReadError: not a gzip file
a: FAIL code 2 (0.08 seconds)
--- tox run -e a --installpkg no_members-1.0.tar.gz -> exit code 2
a: internal error
File "/src/src/tox/tox_env/python/virtual_env/package/cmd_builder.py", line 122, in extract_install_info
StopIteration
a: FAIL code 2 (0.08 seconds)
reported as tox internal error: ['bad_requires-1.0-py3-none-any.whl', 'no_metadata-1.0-py3-none-any.whl', 'not_a_zip-1.0-py3-none-any.whl', 'not_gzip-1.0.tar.gz', 'no_members-1.0.tar.gz']
BUG
Expected: A malformed selected artifact must produce a configuration error.
repro
#!/usr/bin/env python3
import os
import shutil
import subprocess
import sys
from pathlib import Path
REPRO_D = Path("/tmp/repro.d")
work = Path("/tmp/installpkg-malformed")
shutil.rmtree(work, ignore_errors=True)
artifacts = work / "artifacts"
artifacts.mkdir(parents=True)
def tox_run_installpkg(artifact):
project = work / f"project-{artifact}"
project.mkdir()
shutil.copy(REPRO_D / "tox.toml", project)
tox = subprocess.run(
["/opt/venv/bin/tox", "run", "-e", "a", "--installpkg", artifacts / artifact],
cwd=project,
env={**os.environ, "PIP_NO_INDEX": "1"}, # pip is never reached here; if it were, fail instead of going online
capture_output=True,
text=True,
timeout=120,
)
print(f"--- tox run -e a --installpkg {artifact} -> exit code {tox.returncode}")
return tox.returncode, (tox.stdout + tox.stderr).splitlines()
# the artifact producer's part
subprocess.run([sys.executable, REPRO_D / "make_malformed_artifacts.py", artifacts], check=True)
# reference: the malformed wheel tox does check for is rejected as "a: failed with <reason>", exit code 1
_, lines = tox_run_installpkg("no_dist_info-1.0-py3-none-any.whl")
print("\n".join(lines))
# trigger: each of these lets a parse error escape from extract_install_info()
escaping_exception = {
"bad_requires-1.0-py3-none-any.whl": "packaging.requirements.InvalidRequirement",
"no_metadata-1.0-py3-none-any.whl": "importlib.metadata.MetadataNotFound",
"not_a_zip-1.0-py3-none-any.whl": "zipfile.BadZipFile",
"not_gzip-1.0.tar.gz": "tarfile.ReadError",
"no_members-1.0.tar.gz": "StopIteration",
}
reported_as_internal_error = []
for artifact, exception in escaping_exception.items():
code, lines = tox_run_installpkg(artifact)
frame = [line for line in lines if line.endswith("in extract_install_info")]
raised = [line for line in lines if line.startswith(exception)]
print("\n".join(line for line in lines if line.lstrip().startswith("a:") or line in frame + raised))
if code == 2 and "a: internal error" in lines and frame and raised:
reported_as_internal_error.append(artifact)
# check: a rejected artifact must give "a: failed with <reason>" and exit code 1, not an internal error and a traceback
print()
print("reported as tox internal error:", reported_as_internal_error)
print("BUG" if reported_as_internal_error else "OK")repro.d/make_malformed_artifacts.py
#!/usr/bin/env python3
import sys
import tarfile
import zipfile
from pathlib import Path
out = Path(sys.argv[1])
with zipfile.ZipFile(out / "bad_requires-1.0-py3-none-any.whl", "w") as wheel:
wheel.writestr(
"bad_requires-1.0.dist-info/METADATA",
"Metadata-Version: 2.1\nName: bad_requires\nVersion: 1.0\nRequires-Dist: requests => 2.0\n", # "=>" is no operator
)
with zipfile.ZipFile(out / "no_metadata-1.0-py3-none-any.whl", "w") as wheel:
wheel.writestr("no_metadata-1.0.dist-info/WHEEL", "Wheel-Version: 1.0\n")
(out / "not_a_zip-1.0-py3-none-any.whl").write_bytes(b"not a zip archive\n")
(out / "not_gzip-1.0.tar.gz").write_bytes(b"not a gzip stream\n")
with tarfile.open(out / "no_members-1.0.tar.gz", "w:gz"):
pass
# the one malformed wheel tox does check for
with zipfile.ZipFile(out / "no_dist_info-1.0-py3-none-any.whl", "w") as wheel:
wheel.writestr("no_dist_info/__init__.py", "")repro.d/tox.toml
[env.a]
commands = [["python", "-c", "print('tests would run here')"]]Dockerfile.repro (test harness)
FROM python:3.15-bookworm
ENV DEBIAN_FRONTEND=noninteractive \
PIP_DISABLE_PIP_VERSION_CHECK=1
RUN apt-get update && apt-get install -y --no-install-recommends man-db passwd \
&& rm -rf /var/lib/apt/lists/* \
&& useradd --create-home --shell /bin/bash scanner-test
RUN python -m venv /opt/venv
ENV PATH=/opt/venv/bin:$PATH
COPY . /src
WORKDIR /src
RUN pip install --upgrade pip \
&& { git describe --tags >/dev/null 2>&1 || export SETUPTOOLS_SCM_PRETEND_VERSION=0.0.0; } \
&& pip install -e '.[completion]' --group test \
&& pip wheel --no-deps --wheel-dir /opt/wheels .
RUN chown -R scanner-test:scanner-test /src && git config --global --add safe.directory /srcImpact
A malformed artifact selected by --installpkg raises an internal error instead of a configuration error. Reproducibility is moderate and exposure is niche because the selected installpkg artifact must be malformed.
Credits
Anthropic OSS Scanner, ANT-2026-3BMGTL6L.
Activity