mirror of
https://github.com/encode/django-rest-framework.git
synced 2024-11-10 19:56:59 +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