diff --git a/rest_framework/fields.py b/rest_framework/fields.py index ea8f47b2d..eebbfd852 100644 --- a/rest_framework/fields.py +++ b/rest_framework/fields.py @@ -35,6 +35,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: @@ -784,6 +785,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, diff --git a/rest_framework/validators.py b/rest_framework/validators.py index 1cbe31b5e..06f2e8772 100644 --- a/rest_framework/validators.py +++ b/rest_framework/validators.py @@ -174,6 +174,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.')