diff --git a/django/contrib/messages/storage/cookie.py b/django/contrib/messages/storage/cookie.py index a318002127..ca1ae7f6b6 100644 --- a/django/contrib/messages/storage/cookie.py +++ b/django/contrib/messages/storage/cookie.py @@ -33,6 +33,9 @@ class MessageDecoder(json.JSONDecoder): def process_messages(self, obj): if isinstance(obj, list) and obj: if obj[0] == MessageEncoder.message_key: + if len(obj) == 3: + # Compatibility with previously-encoded messages + return Message(*obj[1:]) if obj[1]: obj[3] = mark_safe(obj[3]) return Message(*obj[2:]) diff --git a/django/contrib/messages/tests/test_cookie.py b/django/contrib/messages/tests/test_cookie.py index d44dd94491..10082634f6 100644 --- a/django/contrib/messages/tests/test_cookie.py +++ b/django/contrib/messages/tests/test_cookie.py @@ -153,3 +153,25 @@ class CookieTest(BaseTests, TestCase): encode_decode(mark_safe("Hello Django!")), SafeData) self.assertNotIsInstance( encode_decode("Hello Django!"), SafeData) + + def test_pre_1_5_message_format(self): + """ + For ticket #22426. Tests whether messages that were set in the cookie + before the addition of is_safedata are decoded correctly. + """ + + # Encode the messages using the current encoder. + messages = [Message(constants.INFO, 'message %s') for x in range(5)] + encoder = MessageEncoder(separators=(',', ':')) + encoded_messages = encoder.encode(messages) + + # Remove the is_safedata flag from the messages in order to imitate + # the behavior of before 1.5 (monkey patching). + encoded_messages = json.loads(encoded_messages) + for obj in encoded_messages: + obj.pop(1) + encoded_messages = json.dumps(encoded_messages, separators=(',', ':')) + + # Decode the messages in the old format (without is_safedata) + decoded_messages = json.loads(encoded_messages, cls=MessageDecoder) + self.assertEqual(messages, decoded_messages)