mirror of
https://github.com/Abdess/retroarch_system.git
synced 2026-10-25 13:19:03 -05:00
fix: report a file under a folder no one can enter
Path.exists() lets PermissionError through, so a BIOS subfolder without search permission stopped --check and installs before any file. The file is now reported unreadable and the run goes on with the others.
This commit is contained in:
1 parent
d1414263fa
commit
2f8416e5fe
2 files changed
+123
-20
No files matched your search
@@ -507,6 +507,65 @@ class ARefusedFolderReportsEachFile(unittest.TestCase):
|
||||
list(range(1, len(downloaded) + 1)))
|
||||
|
||||
|
||||
class AFolderThisUserCannotEnter(unittest.TestCase):
|
||||
"""A subfolder of the BIOS folder without search permission (made 0700
|
||||
by an emulator that ran as root, or denied by a Windows ACL) raised
|
||||
PermissionError from Path.exists() before any file was handled, in
|
||||
--check and in an install alike."""
|
||||
|
||||
def _locked(self, repo: FakeRepository) -> Path:
|
||||
(repo.dest / "pcsx").mkdir(parents=True)
|
||||
(repo.dest / "pcsx" / "extra.bin").write_bytes(b"old")
|
||||
os.chmod(repo.dest / "pcsx", 0o000)
|
||||
return repo.dest / "pcsx"
|
||||
|
||||
@unittest.skipIf(os.name == "nt" or os.geteuid() == 0,
|
||||
"a folder without search permission is POSIX")
|
||||
def test_check_names_the_file_and_reads_the_others(self):
|
||||
with FakeRepository() as repo:
|
||||
locked = self._locked(repo)
|
||||
try:
|
||||
proc = repo.run("--check")
|
||||
finally:
|
||||
os.chmod(locked, 0o755)
|
||||
self.assertNotIn("Traceback", proc.stderr)
|
||||
self.assertEqual(proc.returncode, 1, proc.stdout + proc.stderr)
|
||||
self.assertIn("wrong hash: pcsx/extra.bin", proc.stdout)
|
||||
self.assertIn("could not be read (Permission denied)", proc.stdout)
|
||||
self.assertIn("missing: scph5501.bin", proc.stdout)
|
||||
|
||||
@unittest.skipIf(os.name == "nt" or os.geteuid() == 0,
|
||||
"a folder without search permission is POSIX")
|
||||
def test_install_fails_that_file_alone(self):
|
||||
with FakeRepository() as repo:
|
||||
locked = self._locked(repo)
|
||||
try:
|
||||
proc = repo.run("--events")
|
||||
finally:
|
||||
os.chmod(locked, 0o755)
|
||||
installed = repo.installed()
|
||||
self.assertNotIn("Traceback", proc.stderr)
|
||||
events = [json.loads(line) for line in proc.stdout.splitlines()]
|
||||
failed = {e["dest"]: e["reason"] for e in events
|
||||
if e["event"] == "downloaded" and not e["ok"]}
|
||||
self.assertEqual(list(failed), ["pcsx/extra.bin"], proc.stderr)
|
||||
self.assertIn("this user may not have access", failed["pcsx/extra.bin"])
|
||||
self.assertIn("scph5501.bin", installed)
|
||||
self.assertIn("mgba/extra.bin", installed)
|
||||
|
||||
@unittest.skipIf(os.name == "nt" or os.geteuid() == 0,
|
||||
"a folder without search permission is POSIX")
|
||||
def test_declared_state_reads_it_as_wrong(self):
|
||||
with FakeRepository() as repo:
|
||||
locked = self._locked(repo)
|
||||
entry = {"dest": "pcsx/extra.bin", "sha1": "0" * 40, "size": 3}
|
||||
try:
|
||||
state = install._declared_state(entry, entry, repo.dest)
|
||||
finally:
|
||||
os.chmod(locked, 0o755)
|
||||
self.assertEqual(state, "wrong_hash")
|
||||
|
||||
|
||||
class _Tty(io.StringIO):
|
||||
def isatty(self) -> bool:
|
||||
return True
|
||||
|
||||
Reference in new issue
Block a user