mirror of
https://github.com/alexta69/metube.git
synced 2026-07-23 13:22:48 +00:00
fix: force 0600 on fallback state rewrites, not just creation
This commit is contained in:
@@ -153,6 +153,14 @@ class AtomicJsonStore:
|
|||||||
# per-download option overrides that must not leak on shared mounts.
|
# per-download option overrides that must not leak on shared mounts.
|
||||||
fd = os.open(self.path, os.O_WRONLY | os.O_CREAT | os.O_TRUNC, 0o600)
|
fd = os.open(self.path, os.O_WRONLY | os.O_CREAT | os.O_TRUNC, 0o600)
|
||||||
with os.fdopen(fd, "w", encoding="utf-8") as f:
|
with os.fdopen(fd, "w", encoding="utf-8") as f:
|
||||||
|
# The 0o600 mode above only applies when the file is created; force
|
||||||
|
# it on rewrites too so an existing, broadly-permissioned state file
|
||||||
|
# is tightened to match the atomic path. Best-effort because some
|
||||||
|
# network filesystems reject chmod, and that must not re-crash save.
|
||||||
|
try:
|
||||||
|
os.fchmod(f.fileno(), 0o600)
|
||||||
|
except OSError:
|
||||||
|
pass
|
||||||
self._write_payload(payload, f)
|
self._write_payload(payload, f)
|
||||||
f.flush()
|
f.flush()
|
||||||
self._best_effort_fsync(f.fileno())
|
self._best_effort_fsync(f.fileno())
|
||||||
|
|||||||
@@ -41,6 +41,23 @@ class StateStoreTests(unittest.TestCase):
|
|||||||
payload = store.load()
|
payload = store.load()
|
||||||
self.assertEqual(payload["items"], [{"key": "a"}])
|
self.assertEqual(payload["items"], [{"key": "a"}])
|
||||||
|
|
||||||
|
def test_fallback_tightens_permissions_on_existing_file(self):
|
||||||
|
with tempfile.TemporaryDirectory() as tmp:
|
||||||
|
path = os.path.join(tmp, "queue.json")
|
||||||
|
with open(path, "w", encoding="utf-8") as f:
|
||||||
|
f.write("{}")
|
||||||
|
os.chmod(path, 0o644)
|
||||||
|
|
||||||
|
store = AtomicJsonStore(path, kind="persistent_queue:queue")
|
||||||
|
with patch(
|
||||||
|
"state_store.tempfile.mkstemp",
|
||||||
|
side_effect=PermissionError(1, "Operation not permitted"),
|
||||||
|
):
|
||||||
|
store.save({"items": [{"key": "a"}]})
|
||||||
|
|
||||||
|
self.assertEqual(os.stat(path).st_mode & 0o777, 0o600)
|
||||||
|
self.assertEqual(store.load()["items"], [{"key": "a"}])
|
||||||
|
|
||||||
def test_save_falls_back_to_direct_write_when_replace_fails(self):
|
def test_save_falls_back_to_direct_write_when_replace_fails(self):
|
||||||
with tempfile.TemporaryDirectory() as tmp:
|
with tempfile.TemporaryDirectory() as tmp:
|
||||||
path = os.path.join(tmp, "queue.json")
|
path = os.path.join(tmp, "queue.json")
|
||||||
|
|||||||
Reference in New Issue
Block a user