mirror of
				https://github.com/encode/django-rest-framework.git
				synced 2025-11-01 00:17:40 +03:00 
			
		
		
		
	* CharField: Detect and prohibit surrogate characters * CharField: Cover handling of surrogate characters
This commit is contained in:
		
							parent
							
								
									165da5be0c
								
							
						
					
					
						commit
						373e521f36
					
				|  | @ -36,6 +36,7 @@ from rest_framework.exceptions import ErrorDetail, ValidationError | |||
| from rest_framework.settings import api_settings | ||||
| from rest_framework.utils import html, humanize_datetime, json, representation | ||||
| from rest_framework.utils.formatting import lazy_format | ||||
| from rest_framework.validators import ProhibitSurrogateCharactersValidator | ||||
| 
 | ||||
| 
 | ||||
| class empty: | ||||
|  | @ -818,6 +819,7 @@ class CharField(Field): | |||
|         # ProhibitNullCharactersValidator is None on Django < 2.0 | ||||
|         if ProhibitNullCharactersValidator is not None: | ||||
|             self.validators.append(ProhibitNullCharactersValidator()) | ||||
|         self.validators.append(ProhibitSurrogateCharactersValidator()) | ||||
| 
 | ||||
|     def run_validation(self, data=empty): | ||||
|         # Test for the empty string here so that it does not get validated, | ||||
|  |  | |||
|  | @ -167,6 +167,17 @@ class UniqueTogetherValidator: | |||
|         ) | ||||
| 
 | ||||
| 
 | ||||
| class ProhibitSurrogateCharactersValidator: | ||||
|     message = _('Surrogate characters are not allowed: U+{code_point:X}.') | ||||
|     code = 'surrogate_characters_not_allowed' | ||||
| 
 | ||||
|     def __call__(self, value): | ||||
|         for surrogate_character in (ch for ch in str(value) | ||||
|                                     if 0xD800 <= ord(ch) <= 0xDFFF): | ||||
|             message = self.message.format(code_point=ord(surrogate_character)) | ||||
|             raise ValidationError(message, code=self.code) | ||||
| 
 | ||||
| 
 | ||||
| class BaseUniqueForValidator: | ||||
|     message = None | ||||
|     missing_message = _('This field is required.') | ||||
|  |  | |||
|  | @ -758,6 +758,21 @@ class TestCharField(FieldValues): | |||
|                 'Null characters are not allowed.' | ||||
|             ] | ||||
| 
 | ||||
|     def test_surrogate_characters(self): | ||||
|         field = serializers.CharField() | ||||
| 
 | ||||
|         for code_point, expected_message in ( | ||||
|                 (0xD800, 'Surrogate characters are not allowed: U+D800.'), | ||||
|                 (0xDFFF, 'Surrogate characters are not allowed: U+DFFF.'), | ||||
|         ): | ||||
|             with pytest.raises(serializers.ValidationError) as exc_info: | ||||
|                 field.run_validation(chr(code_point)) | ||||
|             assert exc_info.value.detail[0].code == 'surrogate_characters_not_allowed' | ||||
|             assert str(exc_info.value.detail[0]) == expected_message | ||||
| 
 | ||||
|         for code_point in (0xD800 - 1, 0xDFFF + 1): | ||||
|             field.run_validation(chr(code_point)) | ||||
| 
 | ||||
|     def test_iterable_validators(self): | ||||
|         """ | ||||
|         Ensure `validators` parameter is compatible with reasonable iterables. | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	Block a user