mirror of
				https://github.com/encode/django-rest-framework.git
				synced 2025-10-31 07:57:55 +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.settings import api_settings | ||||||
| from rest_framework.utils import html, humanize_datetime, json, representation | from rest_framework.utils import html, humanize_datetime, json, representation | ||||||
| from rest_framework.utils.formatting import lazy_format | from rest_framework.utils.formatting import lazy_format | ||||||
|  | from rest_framework.validators import ProhibitSurrogateCharactersValidator | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class empty: | class empty: | ||||||
|  | @ -818,6 +819,7 @@ class CharField(Field): | ||||||
|         # ProhibitNullCharactersValidator is None on Django < 2.0 |         # ProhibitNullCharactersValidator is None on Django < 2.0 | ||||||
|         if ProhibitNullCharactersValidator is not None: |         if ProhibitNullCharactersValidator is not None: | ||||||
|             self.validators.append(ProhibitNullCharactersValidator()) |             self.validators.append(ProhibitNullCharactersValidator()) | ||||||
|  |         self.validators.append(ProhibitSurrogateCharactersValidator()) | ||||||
| 
 | 
 | ||||||
|     def run_validation(self, data=empty): |     def run_validation(self, data=empty): | ||||||
|         # Test for the empty string here so that it does not get validated, |         # 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: | class BaseUniqueForValidator: | ||||||
|     message = None |     message = None | ||||||
|     missing_message = _('This field is required.') |     missing_message = _('This field is required.') | ||||||
|  |  | ||||||
|  | @ -758,6 +758,21 @@ class TestCharField(FieldValues): | ||||||
|                 'Null characters are not allowed.' |                 '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): |     def test_iterable_validators(self): | ||||||
|         """ |         """ | ||||||
|         Ensure `validators` parameter is compatible with reasonable iterables. |         Ensure `validators` parameter is compatible with reasonable iterables. | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user