|
1 | 1 | import json |
| 2 | +import os |
2 | 3 |
|
| 4 | +import pytest |
3 | 5 |
|
4 | 6 | from taxonopy.manifest import ( |
5 | 7 | MANIFEST_FILENAMES, |
@@ -217,3 +219,49 @@ def test_manifest_written_before_output_files(self, tmp_path): |
217 | 219 | output_file.write_text("data") |
218 | 220 | assert manifest_path.exists() |
219 | 221 | assert output_file.exists() |
| 222 | + |
| 223 | + def test_skips_non_string_entries_in_manifest(self, tmp_path): |
| 224 | + (tmp_path / "valid.csv").write_text("data") |
| 225 | + files = [42, None, "valid.csv", MANIFEST_FILENAMES["resolve"]] |
| 226 | + write_manifest(str(tmp_path), "resolve", "0.2.0", "input/", None, files) |
| 227 | + |
| 228 | + result = delete_from_manifest(str(tmp_path), "resolve") |
| 229 | + |
| 230 | + assert result is True |
| 231 | + assert not (tmp_path / "valid.csv").exists() |
| 232 | + assert not (tmp_path / MANIFEST_FILENAMES["resolve"]).exists() |
| 233 | + |
| 234 | + def test_rejects_path_traversal_in_manifest(self, tmp_path): |
| 235 | + outside = tmp_path.parent / "outside.txt" |
| 236 | + outside.write_text("keep me") |
| 237 | + files = ["../outside.txt", MANIFEST_FILENAMES["resolve"]] |
| 238 | + write_manifest(str(tmp_path), "resolve", "0.2.0", "input/", None, files) |
| 239 | + |
| 240 | + delete_from_manifest(str(tmp_path), "resolve") |
| 241 | + |
| 242 | + assert outside.exists() |
| 243 | + |
| 244 | + def test_rejects_absolute_path_in_manifest(self, tmp_path): |
| 245 | + outside = tmp_path.parent / "outside_abs.txt" |
| 246 | + outside.write_text("keep me") |
| 247 | + files = [str(outside.resolve()), MANIFEST_FILENAMES["resolve"]] |
| 248 | + write_manifest(str(tmp_path), "resolve", "0.2.0", "input/", None, files) |
| 249 | + |
| 250 | + delete_from_manifest(str(tmp_path), "resolve") |
| 251 | + |
| 252 | + assert outside.exists() |
| 253 | + |
| 254 | + def test_rejects_symlink_escape_in_manifest(self, tmp_path): |
| 255 | + outside = tmp_path.parent / "outside_sym.txt" |
| 256 | + outside.write_text("keep me") |
| 257 | + link = tmp_path / "link.txt" |
| 258 | + try: |
| 259 | + link.symlink_to(outside) |
| 260 | + except OSError: |
| 261 | + pytest.skip("symlink creation not permitted on this platform") |
| 262 | + files = ["link.txt", MANIFEST_FILENAMES["resolve"]] |
| 263 | + write_manifest(str(tmp_path), "resolve", "0.2.0", "input/", None, files) |
| 264 | + |
| 265 | + delete_from_manifest(str(tmp_path), "resolve") |
| 266 | + |
| 267 | + assert outside.exists() |
0 commit comments