summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Pope <nick@nickpope.me.uk>2021-09-03 11:26:27 +0200
committerMariusz Felisiak <felisiak.mariusz@gmail.com>2021-09-07 11:59:40 +0200
commit4b82578a6045746e7c470b7881dfcf182fd57048 (patch)
tree644714f0c974d46c817c00e96d1c58367046ab87
parentec2f6ea9c6203524933e08d069733cd00a09ede3 (diff)
downloaddjango-4b82578a6045746e7c470b7881dfcf182fd57048.tar.gz
Refs #33060 -- Ensured cache backends validate keys.
The validate_key() function should be called after make_key() to ensure that the validation is performed on the key that will actually be stored in the cache. Co-authored-by: Mariusz Felisiak <felisiak.mariusz@gmail.com>
-rw-r--r--django/core/cache/backends/db.py11
-rw-r--r--tests/cache/tests.py17
2 files changed, 22 insertions, 6 deletions
diff --git a/django/core/cache/backends/db.py b/django/core/cache/backends/db.py
index b84885f1ef..63598007d0 100644
--- a/django/core/cache/backends/db.py
+++ b/django/core/cache/backends/db.py
@@ -56,8 +56,9 @@ class DatabaseCache(BaseDatabaseCache):
key_map = {}
for key in keys:
- self.validate_key(key)
- key_map[self.make_key(key, version)] = key
+ new_key = self.make_key(key, version)
+ self.validate_key(new_key)
+ key_map[new_key] = key
db = router.db_for_read(self.cache_model_class)
connection = connections[db]
@@ -196,14 +197,16 @@ class DatabaseCache(BaseDatabaseCache):
return True
def delete(self, key, version=None):
+ key = self.make_key(key, version)
self.validate_key(key)
- return self._base_delete_many([self.make_key(key, version)])
+ return self._base_delete_many([key])
def delete_many(self, keys, version=None):
key_list = []
for key in keys:
+ key = self.make_key(key, version)
self.validate_key(key)
- key_list.append(self.make_key(key, version))
+ key_list.append(key)
self._base_delete_many(key_list)
def _base_delete_many(self, keys):
diff --git a/tests/cache/tests.py b/tests/cache/tests.py
index 1b40def85a..0e2f5f7d1f 100644
--- a/tests/cache/tests.py
+++ b/tests/cache/tests.py
@@ -675,7 +675,7 @@ class BaseCacheTests:
finally:
cull_cache._max_entries = old_max_entries
- def _perform_invalid_key_test(self, key, expected_warning):
+ def _perform_invalid_key_test(self, key, expected_warning, key_func=None):
"""
All the builtin backends should warn (except memcached that should
error) on keys that would be refused by memcached. This encourages
@@ -688,7 +688,7 @@ class BaseCacheTests:
return key
old_func = cache.key_func
- cache.key_func = func
+ cache.key_func = key_func or func
tests = [
('add', [key, 1]),
@@ -725,6 +725,19 @@ class BaseCacheTests:
)
self._perform_invalid_key_test(key, expected_warning)
+ def test_invalid_with_version_key_length(self):
+ # Custom make_key() that adds a version to the key and exceeds the
+ # limit.
+ def key_func(key, *args):
+ return key + ':1'
+
+ key = 'a' * 249
+ expected_warning = (
+ 'Cache key will cause errors if used with memcached: '
+ '%r (longer than %s)' % (key_func(key), 250)
+ )
+ self._perform_invalid_key_test(key, expected_warning, key_func=key_func)
+
def test_cache_versioning_get_set(self):
# set, using default version = 1
cache.set('answer1', 42)