Fixed #28201 -- Added ProhibitNullCharactersValidator and used it on CharField form field.
This commit is contained in:
parent
b78d100fa6
commit
90d7b912b9
|
@ -503,3 +503,27 @@ def get_available_image_extensions():
|
|||
validate_image_file_extension = FileExtensionValidator(
|
||||
allowed_extensions=get_available_image_extensions(),
|
||||
)
|
||||
|
||||
|
||||
@deconstructible
|
||||
class ProhibitNullCharactersValidator:
|
||||
"""Validate that the string doesn't contain the null character."""
|
||||
message = _('Null characters are not allowed.')
|
||||
code = 'null_characters_not_allowed'
|
||||
|
||||
def __init__(self, message=None, code=None):
|
||||
if message is not None:
|
||||
self.message = message
|
||||
if code is not None:
|
||||
self.code = code
|
||||
|
||||
def __call__(self, value):
|
||||
if '\x00' in str(value):
|
||||
raise ValidationError(self.message, code=self.code)
|
||||
|
||||
def __eq__(self, other):
|
||||
return (
|
||||
isinstance(other, self.__class__) and
|
||||
self.message == other.message and
|
||||
self.code == other.code
|
||||
)
|
||||
|
|
|
@ -217,6 +217,7 @@ class CharField(Field):
|
|||
self.validators.append(validators.MinLengthValidator(int(min_length)))
|
||||
if max_length is not None:
|
||||
self.validators.append(validators.MaxLengthValidator(int(max_length)))
|
||||
self.validators.append(validators.ProhibitNullCharactersValidator())
|
||||
|
||||
def to_python(self, value):
|
||||
"""Return a string."""
|
||||
|
|
|
@ -304,3 +304,27 @@ to, or in lieu of custom ``field.clean()`` methods.
|
|||
Uses Pillow to ensure that ``value.name`` (``value`` is a
|
||||
:class:`~django.core.files.File`) has `a valid image extension
|
||||
<https://pillow.readthedocs.io/en/latest/handbook/image-file-formats.html>`_.
|
||||
|
||||
``ProhibitNullCharactersValidator``
|
||||
-----------------------------------
|
||||
|
||||
.. class:: ProhibitNullCharactersValidator(message=None, code=None)
|
||||
|
||||
.. versionadded:: 2.0
|
||||
|
||||
Raises a :exc:`~django.core.exceptions.ValidationError` if ``str(value)``
|
||||
contains one or more nulls characters (``'\x00'``).
|
||||
|
||||
:param message: If not ``None``, overrides :attr:`.message`.
|
||||
:param code: If not ``None``, overrides :attr:`code`.
|
||||
|
||||
.. attribute:: message
|
||||
|
||||
The error message used by
|
||||
:exc:`~django.core.exceptions.ValidationError` if validation fails.
|
||||
Defaults to ``"Null characters are not allowed."``.
|
||||
|
||||
.. attribute:: code
|
||||
|
||||
The error code used by :exc:`~django.core.exceptions.ValidationError`
|
||||
if validation fails. Defaults to ``"null_characters_not_allowed"``.
|
||||
|
|
|
@ -318,7 +318,12 @@ URLs
|
|||
Validators
|
||||
~~~~~~~~~~
|
||||
|
||||
* ...
|
||||
* The new :class:`.ProhibitNullCharactersValidator` disallows the null
|
||||
character in the input of the :class:`~django.forms.CharField` form field
|
||||
and its subclasses. Null character input was observed from vulnerability
|
||||
scanning tools. Most databases silently discard null characters, but
|
||||
psycopg2 2.7+ raises an exception when trying to save a null character to
|
||||
a char/text field with PostgreSQL.
|
||||
|
||||
.. _backwards-incompatible-2.0:
|
||||
|
||||
|
|
|
@ -123,3 +123,9 @@ class CharFieldTest(FormFieldAssertionsMixin, SimpleTestCase):
|
|||
def test_charfield_disabled(self):
|
||||
f = CharField(disabled=True)
|
||||
self.assertWidgetRendersTo(f, '<input type="text" name="f" id="id_f" disabled required />')
|
||||
|
||||
def test_null_characters_prohibited(self):
|
||||
f = CharField()
|
||||
msg = 'Null characters are not allowed.'
|
||||
with self.assertRaisesMessage(ValidationError, msg):
|
||||
f.clean('\x00something')
|
||||
|
|
|
@ -9,11 +9,11 @@ from django.core.files.base import ContentFile
|
|||
from django.core.validators import (
|
||||
BaseValidator, DecimalValidator, EmailValidator, FileExtensionValidator,
|
||||
MaxLengthValidator, MaxValueValidator, MinLengthValidator,
|
||||
MinValueValidator, RegexValidator, URLValidator, int_list_validator,
|
||||
validate_comma_separated_integer_list, validate_email,
|
||||
validate_image_file_extension, validate_integer, validate_ipv4_address,
|
||||
validate_ipv6_address, validate_ipv46_address, validate_slug,
|
||||
validate_unicode_slug,
|
||||
MinValueValidator, ProhibitNullCharactersValidator, RegexValidator,
|
||||
URLValidator, int_list_validator, validate_comma_separated_integer_list,
|
||||
validate_email, validate_image_file_extension, validate_integer,
|
||||
validate_ipv4_address, validate_ipv6_address, validate_ipv46_address,
|
||||
validate_slug, validate_unicode_slug,
|
||||
)
|
||||
from django.test import SimpleTestCase
|
||||
|
||||
|
@ -264,6 +264,10 @@ TEST_DATA = [
|
|||
(validate_image_file_extension, ContentFile('contents', name='file.PNG'), None),
|
||||
(validate_image_file_extension, ContentFile('contents', name='file.txt'), ValidationError),
|
||||
(validate_image_file_extension, ContentFile('contents', name='file'), ValidationError),
|
||||
|
||||
(ProhibitNullCharactersValidator(), '\x00something', ValidationError),
|
||||
(ProhibitNullCharactersValidator(), 'something', None),
|
||||
(ProhibitNullCharactersValidator(), None, None),
|
||||
]
|
||||
|
||||
|
||||
|
@ -488,3 +492,21 @@ class TestValidatorEquality(TestCase):
|
|||
FileExtensionValidator(['txt']),
|
||||
FileExtensionValidator(['txt'], message='custom error message')
|
||||
)
|
||||
|
||||
def test_prohibit_null_characters_validator_equality(self):
|
||||
self.assertEqual(
|
||||
ProhibitNullCharactersValidator(message='message', code='code'),
|
||||
ProhibitNullCharactersValidator(message='message', code='code')
|
||||
)
|
||||
self.assertEqual(
|
||||
ProhibitNullCharactersValidator(),
|
||||
ProhibitNullCharactersValidator()
|
||||
)
|
||||
self.assertNotEqual(
|
||||
ProhibitNullCharactersValidator(message='message1', code='code'),
|
||||
ProhibitNullCharactersValidator(message='message2', code='code')
|
||||
)
|
||||
self.assertNotEqual(
|
||||
ProhibitNullCharactersValidator(message='message', code='code1'),
|
||||
ProhibitNullCharactersValidator(message='message', code='code2')
|
||||
)
|
||||
|
|
Loading…
Reference in New Issue