mirror of
				https://github.com/django/django.git
				synced 2025-10-31 09:41:08 +00:00 
			
		
		
		
	Fixed #19387 -- Preserved SafeData status in contrib.messages
Thanks Anton Baklanov for the report and the patch.
This commit is contained in:
		| @@ -4,6 +4,7 @@ from django.conf import settings | ||||
| from django.contrib.messages.storage.base import BaseStorage, Message | ||||
| from django.http import SimpleCookie | ||||
| from django.utils.crypto import salted_hmac, constant_time_compare | ||||
| from django.utils.safestring import SafeData, mark_safe | ||||
| from django.utils import six | ||||
|  | ||||
|  | ||||
| @@ -15,7 +16,9 @@ class MessageEncoder(json.JSONEncoder): | ||||
|  | ||||
|     def default(self, obj): | ||||
|         if isinstance(obj, Message): | ||||
|             message = [self.message_key, obj.level, obj.message] | ||||
|             # Using 0/1 here instead of False/True to produce more compact json | ||||
|             is_safedata = 1 if isinstance(obj.message, SafeData) else 0 | ||||
|             message = [self.message_key, is_safedata, obj.level, obj.message] | ||||
|             if obj.extra_tags: | ||||
|                 message.append(obj.extra_tags) | ||||
|             return message | ||||
| @@ -30,7 +33,9 @@ class MessageDecoder(json.JSONDecoder): | ||||
|     def process_messages(self, obj): | ||||
|         if isinstance(obj, list) and obj: | ||||
|             if obj[0] == MessageEncoder.message_key: | ||||
|                 return Message(*obj[1:]) | ||||
|                 if obj[1]: | ||||
|                     obj[3] = mark_safe(obj[3]) | ||||
|                 return Message(*obj[2:]) | ||||
|             return [self.process_messages(item) for item in obj] | ||||
|         if isinstance(obj, dict): | ||||
|             return dict([(key, self.process_messages(value)) | ||||
|   | ||||
| @@ -6,6 +6,7 @@ from django.contrib.messages.storage.cookie import (CookieStorage, | ||||
|     MessageEncoder, MessageDecoder) | ||||
| from django.contrib.messages.storage.base import Message | ||||
| from django.test.utils import override_settings | ||||
| from django.utils.safestring import SafeData, mark_safe | ||||
|  | ||||
|  | ||||
| def set_cookie_data(storage, messages, invalid=False, encode_empty=False): | ||||
| @@ -132,3 +133,21 @@ class CookieTest(BaseTest): | ||||
|         value = encoder.encode(messages) | ||||
|         decoded_messages = json.loads(value, cls=MessageDecoder) | ||||
|         self.assertEqual(messages, decoded_messages) | ||||
|  | ||||
|     def test_safedata(self): | ||||
|         """ | ||||
|         Tests that a message containing SafeData is keeping its safe status when | ||||
|         retrieved from the message storage. | ||||
|         """ | ||||
|         def encode_decode(data): | ||||
|             message = Message(constants.DEBUG, data) | ||||
|             encoded = storage._encode(message) | ||||
|             decoded = storage._decode(encoded) | ||||
|             return decoded.message | ||||
|  | ||||
|         storage = self.get_storage() | ||||
|  | ||||
|         self.assertIsInstance( | ||||
|             encode_decode(mark_safe("<b>Hello Django!</b>")), SafeData) | ||||
|         self.assertNotIsInstance( | ||||
|             encode_decode("<b>Hello Django!</b>"), SafeData) | ||||
|   | ||||
| @@ -1,5 +1,8 @@ | ||||
| from django.contrib.messages import constants | ||||
| from django.contrib.messages.tests.base import BaseTest | ||||
| from django.contrib.messages.storage.base import Message | ||||
| from django.contrib.messages.storage.session import SessionStorage | ||||
| from django.utils.safestring import SafeData, mark_safe | ||||
|  | ||||
|  | ||||
| def set_session_data(storage, messages): | ||||
| @@ -36,3 +39,14 @@ class SessionTest(BaseTest): | ||||
|         set_session_data(storage, example_messages) | ||||
|         # Test that the message actually contains what we expect. | ||||
|         self.assertEqual(list(storage), example_messages) | ||||
|  | ||||
|     def test_safedata(self): | ||||
|         """ | ||||
|         Tests that a message containing SafeData is keeping its safe status when | ||||
|         retrieved from the message storage. | ||||
|         """ | ||||
|         storage = self.get_storage() | ||||
|  | ||||
|         message = Message(constants.DEBUG, mark_safe("<b>Hello Django!</b>")) | ||||
|         set_session_data(storage, [message]) | ||||
|         self.assertIsInstance(list(storage)[0].message, SafeData) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user