Fixed #29550 -- Eased overriding pickle.dumps() protocol in cache backends and session serializer.

This commit is contained in:
Simon Charette 2018-07-06 17:55:46 -04:00 committed by Tim Graham
parent 2d75509bcb
commit 37835883ad
4 changed files with 14 additions and 7 deletions

View File

@ -8,8 +8,10 @@ class PickleSerializer:
Simple wrapper around pickle to be used in signing.dumps and Simple wrapper around pickle to be used in signing.dumps and
signing.loads. signing.loads.
""" """
protocol = pickle.HIGHEST_PROTOCOL
def dumps(self, obj): def dumps(self, obj):
return pickle.dumps(obj, pickle.HIGHEST_PROTOCOL) return pickle.dumps(obj, self.protocol)
def loads(self, data): def loads(self, data):
return pickle.loads(data) return pickle.loads(data)

View File

@ -46,6 +46,8 @@ class DatabaseCache(BaseDatabaseCache):
# conversion and adaptation infrastructure is then used to avoid comparing # conversion and adaptation infrastructure is then used to avoid comparing
# aware and naive datetimes accidentally. # aware and naive datetimes accidentally.
pickle_protocol = pickle.HIGHEST_PROTOCOL
def get(self, key, default=None, version=None): def get(self, key, default=None, version=None):
key = self.make_key(key, version=version) key = self.make_key(key, version=version)
self.validate_key(key) self.validate_key(key)
@ -130,7 +132,7 @@ class DatabaseCache(BaseDatabaseCache):
exp = exp.replace(microsecond=0) exp = exp.replace(microsecond=0)
if num > self._max_entries: if num > self._max_entries:
self._cull(db, cursor, now) self._cull(db, cursor, now)
pickled = pickle.dumps(value, pickle.HIGHEST_PROTOCOL) pickled = pickle.dumps(value, self.pickle_protocol)
# The DB column is expecting a string, so make sure the value is a # The DB column is expecting a string, so make sure the value is a
# string, not bytes. Refs #19274. # string, not bytes. Refs #19274.
b64encoded = base64.b64encode(pickled).decode('latin1') b64encoded = base64.b64encode(pickled).decode('latin1')

View File

@ -15,6 +15,7 @@ from django.core.files.move import file_move_safe
class FileBasedCache(BaseCache): class FileBasedCache(BaseCache):
cache_suffix = '.djcache' cache_suffix = '.djcache'
pickle_protocol = pickle.HIGHEST_PROTOCOL
def __init__(self, dir, params): def __init__(self, dir, params):
super().__init__(params) super().__init__(params)
@ -39,8 +40,8 @@ class FileBasedCache(BaseCache):
def _write_content(self, file, timeout, value): def _write_content(self, file, timeout, value):
expiry = self.get_backend_timeout(timeout) expiry = self.get_backend_timeout(timeout)
file.write(pickle.dumps(expiry, pickle.HIGHEST_PROTOCOL)) file.write(pickle.dumps(expiry, self.pickle_protocol))
file.write(zlib.compress(pickle.dumps(value, pickle.HIGHEST_PROTOCOL))) file.write(zlib.compress(pickle.dumps(value, self.pickle_protocol)))
def set(self, key, value, timeout=DEFAULT_TIMEOUT, version=None): def set(self, key, value, timeout=DEFAULT_TIMEOUT, version=None):
self._createdir() # Cache dir can be deleted at any time. self._createdir() # Cache dir can be deleted at any time.

View File

@ -14,6 +14,8 @@ _locks = {}
class LocMemCache(BaseCache): class LocMemCache(BaseCache):
pickle_protocol = pickle.HIGHEST_PROTOCOL
def __init__(self, name, params): def __init__(self, name, params):
super().__init__(params) super().__init__(params)
self._cache = _caches.setdefault(name, OrderedDict()) self._cache = _caches.setdefault(name, OrderedDict())
@ -23,7 +25,7 @@ class LocMemCache(BaseCache):
def add(self, key, value, timeout=DEFAULT_TIMEOUT, version=None): def add(self, key, value, timeout=DEFAULT_TIMEOUT, version=None):
key = self.make_key(key, version=version) key = self.make_key(key, version=version)
self.validate_key(key) self.validate_key(key)
pickled = pickle.dumps(value, pickle.HIGHEST_PROTOCOL) pickled = pickle.dumps(value, self.pickle_protocol)
with self._lock: with self._lock:
if self._has_expired(key): if self._has_expired(key):
self._set(key, pickled, timeout) self._set(key, pickled, timeout)
@ -51,7 +53,7 @@ class LocMemCache(BaseCache):
def set(self, key, value, timeout=DEFAULT_TIMEOUT, version=None): def set(self, key, value, timeout=DEFAULT_TIMEOUT, version=None):
key = self.make_key(key, version=version) key = self.make_key(key, version=version)
self.validate_key(key) self.validate_key(key)
pickled = pickle.dumps(value, pickle.HIGHEST_PROTOCOL) pickled = pickle.dumps(value, self.pickle_protocol)
with self._lock: with self._lock:
self._set(key, pickled, timeout) self._set(key, pickled, timeout)
@ -73,7 +75,7 @@ class LocMemCache(BaseCache):
pickled = self._cache[key] pickled = self._cache[key]
value = pickle.loads(pickled) value = pickle.loads(pickled)
new_value = value + delta new_value = value + delta
pickled = pickle.dumps(new_value, pickle.HIGHEST_PROTOCOL) pickled = pickle.dumps(new_value, self.pickle_protocol)
self._cache[key] = pickled self._cache[key] = pickled
self._cache.move_to_end(key, last=False) self._cache.move_to_end(key, last=False)
return new_value return new_value