This is an automated email from the ASF dual-hosted git repository. imbajin pushed a commit to branch feat/oink-core-platform in repository https://gitbox.apache.org/repos/asf/hugegraph-doc.git
commit 401134d043abcfac7e9a176f5509e46698a2b881 Author: dark <[email protected]> AuthorDate: Fri Sep 4 22:40:33 2026 +0800 fix(versioning): validate runner temp ancestry - inspect RUNNER_TEMP components before trusting the root - preserve trusted system temporary directory aliases - cover ancestor symlink rejection and real-root cleanup --- scripts/test_versioning.py | 50 ++++++++++++++++++++++++++++++++++++++++++++++ scripts/versioning.py | 11 +++++----- 2 files changed, 55 insertions(+), 6 deletions(-) diff --git a/scripts/test_versioning.py b/scripts/test_versioning.py index 067e18100..1216e5147 100644 --- a/scripts/test_versioning.py +++ b/scripts/test_versioning.py @@ -1290,6 +1290,56 @@ class VersionUrlTest(unittest.TestCase): self.assertEqual(sentinel.read_text(encoding="utf-8"), "keep") self.assertTrue(output.is_dir()) + def test_output_cleanup_rejects_symlink_above_runner_temp_before_resolve( + self, + ) -> None: + with tempfile.TemporaryDirectory() as temp_name: + temp = Path(temp_name) + target = temp / "target" + runner_temp_target = target / "runner-temp" + output = runner_temp_target / "output" + output.mkdir(parents=True) + sentinel = output / "sentinel" + sentinel.write_text("keep", encoding="utf-8") + linked_parent = temp / "linked-parent" + linked_parent.symlink_to(target, target_is_directory=True) + runner_temp = linked_parent / "runner-temp" + + with ( + mock.patch.dict( + versioning.os.environ, + {"RUNNER_TEMP": str(runner_temp)}, + ), + self.assertRaisesRegex(SystemExit, "symbolic link"), + ): + versioning.prepare_output_directory( + runner_temp / "output", + "fixture", + ) + + self.assertEqual(sentinel.read_text(encoding="utf-8"), "keep") + self.assertTrue(output.is_dir()) + + def test_output_cleanup_accepts_real_runner_temp_below_tmp_alias( + self, + ) -> None: + with tempfile.TemporaryDirectory(dir="/tmp") as temp_name: + runner_temp = Path(temp_name) / "runner-temp" + output = runner_temp / "output" + output.mkdir(parents=True) + (output / "stale").write_text("remove", encoding="utf-8") + + with mock.patch.dict( + versioning.os.environ, + {"RUNNER_TEMP": str(runner_temp)}, + ): + self.assertEqual( + versioning.prepare_output_directory(output, "fixture"), + output.resolve(), + ) + + self.assertFalse(output.exists()) + def test_output_cleanup_rejects_registered_sibling_worktree(self) -> None: with tempfile.TemporaryDirectory() as temp_name: sibling = Path(temp_name) / "registered-sibling" diff --git a/scripts/versioning.py b/scripts/versioning.py index dade4b69b..777e5ae50 100644 --- a/scripts/versioning.py +++ b/scripts/versioning.py @@ -349,12 +349,11 @@ def prepare_output_directory(path: pathlib.Path, label: str) -> pathlib.Path: } runner_temp = os.environ.get("RUNNER_TEMP") if runner_temp: - runner_temp_root = pathlib.Path(runner_temp).expanduser() - if runner_temp_root.is_symlink(): - fail( - "RUNNER_TEMP must not be a symbolic link: " - f"{runner_temp_root}" - ) + runner_temp_root = require_no_symlinked_output_components( + pathlib.Path(runner_temp).expanduser(), + "RUNNER_TEMP", + controlled_roots, + ) controlled_roots.add(runner_temp_root) raw_absolute = require_no_symlinked_output_components( raw, label, controlled_roots
