Fix arc_tmp_path UnboundLocalError in workflow install; add preset symlink rejection test

Agent-Logs-Url: https://github.com/github/spec-kit/sessions/0469bac5-296a-46b6-b84e-eb33b0dc0fce

Co-authored-by: mnriem <15701806+mnriem@users.noreply.github.com>
This commit is contained in:
copilot-swe-agent[bot]
2026-05-06 21:27:40 +00:00
committed by GitHub
parent cb87a410f8
commit e0495ebc38
2 changed files with 25 additions and 6 deletions

View File

@@ -5079,16 +5079,18 @@ def workflow_add(
if archive_fmt in ("tar.gz", "zip"):
# Extract workflow.yml from the archive.
suffix = ".tar.gz" if archive_fmt == "tar.gz" else ".zip"
arc_tmp_path = None
with tempfile.NamedTemporaryFile(suffix=suffix, delete=False) as arc_tmp:
arc_tmp.write(raw_data)
arc_tmp_path = Path(arc_tmp.name)
arc_tmp.write(raw_data)
try:
wf_yaml = _extract_workflow_yml(arc_tmp_path, archive_fmt)
with tempfile.NamedTemporaryFile(suffix=".yml", delete=False) as tmp:
tmp.write(wf_yaml)
tmp_path = Path(tmp.name)
tmp.write(wf_yaml)
finally:
arc_tmp_path.unlink(missing_ok=True)
if arc_tmp_path is not None:
arc_tmp_path.unlink(missing_ok=True)
else:
# Treat as a plain YAML file (existing behaviour).
with tempfile.NamedTemporaryFile(suffix=".yml", delete=False) as tmp:
@@ -5125,9 +5127,10 @@ def workflow_add(
console.print(f"[red]Error:[/red] Failed to extract workflow from archive: {exc}")
raise typer.Exit(1)
import tempfile
tmp_local = None
with tempfile.NamedTemporaryFile(suffix=".yml", delete=False) as tmp:
tmp.write(wf_yaml)
tmp_local = Path(tmp.name)
tmp.write(wf_yaml)
try:
_validate_and_install_local(tmp_local, str(source_path))
finally:
@@ -5231,13 +5234,15 @@ def workflow_add(
if cat_archive_fmt in ("tar.gz", "zip"):
# Download URL points to an archive — extract workflow.yml from it.
suffix = ".tar.gz" if cat_archive_fmt == "tar.gz" else ".zip"
arc_tmp = None
with tempfile.NamedTemporaryFile(suffix=suffix, delete=False) as arc_f:
arc_f.write(raw_response)
arc_tmp = Path(arc_f.name)
arc_f.write(raw_response)
try:
wf_yaml_bytes = _extract_workflow_yml(arc_tmp, cat_archive_fmt)
finally:
arc_tmp.unlink(missing_ok=True)
if arc_tmp is not None:
arc_tmp.unlink(missing_ok=True)
workflow_file.write_bytes(wf_yaml_bytes)
else:
workflow_file.write_bytes(raw_response)

View File

@@ -719,6 +719,20 @@ class TestPresetManager:
with pytest.raises(PresetValidationError, match="Unsafe path"):
manager.install_from_zip(archive, "0.1.5")
def test_install_from_tar_gz_rejects_symlinks(self, project_dir, temp_dir):
"""install_from_zip must reject tarballs containing symlinks."""
import tarfile
archive = temp_dir / "symlink.tar.gz"
with tarfile.open(archive, "w:gz") as tf:
info = tarfile.TarInfo(name="link")
info.type = tarfile.SYMTYPE
info.linkname = "/etc/passwd"
tf.addfile(info)
manager = PresetManager(project_dir)
with pytest.raises(PresetValidationError, match="Symlinks"):
manager.install_from_zip(archive, "0.1.5")
def test_remove(self, project_dir, pack_dir):
"""Test removing a preset."""
manager = PresetManager(project_dir)