summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarti Raudsepp <marti@juffo.org>2022-12-13 11:20:25 +0200
committerMariusz Felisiak <felisiak.mariusz@gmail.com>2022-12-13 19:29:15 +0100
commit32268456d6494483f9a737dc7c32bbbf1eceab8c (patch)
tree2bba75bf71f911c549f811cb7c4fcb0d92ec30b6
parent1d0fa848e084cad62d0bb6bde3b51e4862558e57 (diff)
downloaddjango-32268456d6494483f9a737dc7c32bbbf1eceab8c.tar.gz
Fixed #34209 -- Prevented FileBasedCache.has_key() crash caused by a race condition.
-rw-r--r--django/core/cache/backends/filebased.py5
-rw-r--r--tests/cache/tests.py6
2 files changed, 9 insertions, 2 deletions
diff --git a/django/core/cache/backends/filebased.py b/django/core/cache/backends/filebased.py
index 631da49444..215fefbcc0 100644
--- a/django/core/cache/backends/filebased.py
+++ b/django/core/cache/backends/filebased.py
@@ -90,10 +90,11 @@ class FileBasedCache(BaseCache):
def has_key(self, key, version=None):
fname = self._key_to_file(key, version)
- if os.path.exists(fname):
+ try:
with open(fname, "rb") as f:
return not self._is_expired(f)
- return False
+ except FileNotFoundError:
+ return False
def _cull(self):
"""
diff --git a/tests/cache/tests.py b/tests/cache/tests.py
index 937a55acc5..c4d4522514 100644
--- a/tests/cache/tests.py
+++ b/tests/cache/tests.py
@@ -1762,6 +1762,12 @@ class FileBasedCacheTests(BaseCacheTests, TestCase):
with open(cache_file, "rb") as fh:
self.assertIs(cache._is_expired(fh), True)
+ def test_has_key_race_handling(self):
+ self.assertIs(cache.add("key", "value"), True)
+ with mock.patch("builtins.open", side_effect=FileNotFoundError) as mocked_open:
+ self.assertIs(cache.has_key("key"), False)
+ mocked_open.assert_called_once()
+
@unittest.skipUnless(RedisCache_params, "Redis backend not configured")
@override_settings(