mirror of https://github.com/django/django.git
Fixed #35483 -- Added NUL (0x00) character validation to ModelChoiceFields.
Applied the ProhibitNullCharactersValidator to ModelChoiceField and ModelMultipleChoiceField. Co-authored-by: Viktor Paripás <viktor.paripas@gmail.com> Co-authored-by: Vasyl Dizhak <vasyl@dizhak.com> Co-authored-by: Arthur Vasconcelos <vasconcelos.arthur@gmail.com>
This commit is contained in:
parent
fa78481467
commit
38ad710aba
|
@ -11,6 +11,7 @@ from django.core.exceptions import (
|
||||||
ImproperlyConfigured,
|
ImproperlyConfigured,
|
||||||
ValidationError,
|
ValidationError,
|
||||||
)
|
)
|
||||||
|
from django.core.validators import ProhibitNullCharactersValidator
|
||||||
from django.db.models.utils import AltersData
|
from django.db.models.utils import AltersData
|
||||||
from django.forms.fields import ChoiceField, Field
|
from django.forms.fields import ChoiceField, Field
|
||||||
from django.forms.forms import BaseForm, DeclarativeFieldsMetaclass
|
from django.forms.forms import BaseForm, DeclarativeFieldsMetaclass
|
||||||
|
@ -1487,6 +1488,10 @@ class ModelChoiceField(ChoiceField):
|
||||||
self.limit_choices_to = limit_choices_to # limit the queryset later.
|
self.limit_choices_to = limit_choices_to # limit the queryset later.
|
||||||
self.to_field_name = to_field_name
|
self.to_field_name = to_field_name
|
||||||
|
|
||||||
|
def validate_no_null_characters(self, value):
|
||||||
|
non_null_character_validator = ProhibitNullCharactersValidator()
|
||||||
|
return non_null_character_validator(value)
|
||||||
|
|
||||||
def get_limit_choices_to(self):
|
def get_limit_choices_to(self):
|
||||||
"""
|
"""
|
||||||
Return ``limit_choices_to`` for this form field.
|
Return ``limit_choices_to`` for this form field.
|
||||||
|
@ -1551,6 +1556,7 @@ class ModelChoiceField(ChoiceField):
|
||||||
def to_python(self, value):
|
def to_python(self, value):
|
||||||
if value in self.empty_values:
|
if value in self.empty_values:
|
||||||
return None
|
return None
|
||||||
|
self.validate_no_null_characters(value)
|
||||||
try:
|
try:
|
||||||
key = self.to_field_name or "pk"
|
key = self.to_field_name or "pk"
|
||||||
if isinstance(value, self.queryset.model):
|
if isinstance(value, self.queryset.model):
|
||||||
|
@ -1631,6 +1637,7 @@ class ModelMultipleChoiceField(ModelChoiceField):
|
||||||
code="invalid_list",
|
code="invalid_list",
|
||||||
)
|
)
|
||||||
for pk in value:
|
for pk in value:
|
||||||
|
self.validate_no_null_characters(pk)
|
||||||
try:
|
try:
|
||||||
self.queryset.filter(**{key: pk})
|
self.queryset.filter(**{key: pk})
|
||||||
except (ValueError, TypeError):
|
except (ValueError, TypeError):
|
||||||
|
|
|
@ -7,7 +7,7 @@ from django.forms.widgets import CheckboxSelectMultiple
|
||||||
from django.template import Context, Template
|
from django.template import Context, Template
|
||||||
from django.test import TestCase
|
from django.test import TestCase
|
||||||
|
|
||||||
from .models import Article, Author, Book, Category, Writer
|
from .models import Article, Author, Book, Category, ExplicitPK, Writer
|
||||||
|
|
||||||
|
|
||||||
class ModelChoiceFieldTests(TestCase):
|
class ModelChoiceFieldTests(TestCase):
|
||||||
|
@ -79,6 +79,12 @@ class ModelChoiceFieldTests(TestCase):
|
||||||
self.assertEqual(f.clean(self.c1.slug), self.c1)
|
self.assertEqual(f.clean(self.c1.slug), self.c1)
|
||||||
self.assertEqual(f.clean(self.c1), self.c1)
|
self.assertEqual(f.clean(self.c1), self.c1)
|
||||||
|
|
||||||
|
def test_model_choice_null_characters(self):
|
||||||
|
f = forms.ModelChoiceField(queryset=ExplicitPK.objects.all())
|
||||||
|
msg = "Null characters are not allowed."
|
||||||
|
with self.assertRaisesMessage(ValidationError, msg):
|
||||||
|
f.clean("\x00something")
|
||||||
|
|
||||||
def test_choices(self):
|
def test_choices(self):
|
||||||
f = forms.ModelChoiceField(
|
f = forms.ModelChoiceField(
|
||||||
Category.objects.filter(pk=self.c1.id), required=False
|
Category.objects.filter(pk=self.c1.id), required=False
|
||||||
|
|
|
@ -2227,6 +2227,15 @@ class ModelMultipleChoiceFieldTests(TestCase):
|
||||||
f = forms.ModelMultipleChoiceField(queryset=Writer.objects.all())
|
f = forms.ModelMultipleChoiceField(queryset=Writer.objects.all())
|
||||||
self.assertNumQueries(1, f.clean, [p.pk for p in persons[1:11:2]])
|
self.assertNumQueries(1, f.clean, [p.pk for p in persons[1:11:2]])
|
||||||
|
|
||||||
|
def test_model_multiple_choice_null_characters(self):
|
||||||
|
f = forms.ModelMultipleChoiceField(queryset=ExplicitPK.objects.all())
|
||||||
|
msg = "Null characters are not allowed."
|
||||||
|
with self.assertRaisesMessage(ValidationError, msg):
|
||||||
|
f.clean(["\x00something"])
|
||||||
|
|
||||||
|
with self.assertRaisesMessage(ValidationError, msg):
|
||||||
|
f.clean(["valid", "\x00something"])
|
||||||
|
|
||||||
def test_model_multiple_choice_run_validators(self):
|
def test_model_multiple_choice_run_validators(self):
|
||||||
"""
|
"""
|
||||||
ModelMultipleChoiceField run given validators (#14144).
|
ModelMultipleChoiceField run given validators (#14144).
|
||||||
|
|
Loading…
Reference in New Issue