From 780eaa4779c5e6bd6bdc2c34e71aeae5d1b0dbbd Mon Sep 17 00:00:00 2001 From: Aymeric Augustin Date: Sun, 28 Oct 2012 16:42:34 +0100 Subject: [PATCH] [1.5.x] Required serializer to use bytes in loads/dumps loads has no way to tell if it should provide text or bytes to the serializer; bytes are more reasonnable for a serialized representation, and are the only option for pickled data. dumps can perform conversions on the value it receives from the serializer; but for consistency it seems better to require bytes too. The current code would cause an exception when loading pickled session data. See next commit. Also fixed a bug when checking for compressed data. Backport of 58a086a from master. --- django/core/signing.py | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/django/core/signing.py b/django/core/signing.py index 147e54780c..92ab968123 100644 --- a/django/core/signing.py +++ b/django/core/signing.py @@ -97,10 +97,10 @@ class JSONSerializer(object): signing.loads. """ def dumps(self, obj): - return json.dumps(obj, separators=(',', ':')) + return json.dumps(obj, separators=(',', ':')).encode('latin-1') def loads(self, data): - return json.loads(data) + return json.loads(data.decode('latin-1')) def dumps(obj, key=None, salt='django.core.signing', serializer=JSONSerializer, compress=False): @@ -116,8 +116,10 @@ def dumps(obj, key=None, salt='django.core.signing', serializer=JSONSerializer, only valid for a given namespace. Leaving this at the default value or re-using a salt value across different parts of your application without good cause is a security risk. + + The serializer is expected to return a bytestring. """ - data = force_bytes(serializer().dumps(obj)) + data = serializer().dumps(obj) # Flag for if it's been compressed or not is_compressed = False @@ -136,20 +138,22 @@ def dumps(obj, key=None, salt='django.core.signing', serializer=JSONSerializer, def loads(s, key=None, salt='django.core.signing', serializer=JSONSerializer, max_age=None): """ - Reverse of dumps(), raises BadSignature if signature fails + Reverse of dumps(), raises BadSignature if signature fails. + + The serializer is expected to accept a bytestring. """ # TimestampSigner.unsign always returns unicode but base64 and zlib # compression operate on bytes. base64d = force_bytes(TimestampSigner(key, salt=salt).unsign(s, max_age=max_age)) decompress = False - if base64d[0] == b'.': + if base64d[:1] == b'.': # It's compressed; uncompress it first base64d = base64d[1:] decompress = True data = b64_decode(base64d) if decompress: data = zlib.decompress(data) - return serializer().loads(force_str(data)) + return serializer().loads(data) class Signer(object):