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:
Alexander Lötvall 2024-06-08 12:14:46 +02:00 committed by Sarah Boyce
parent fa78481467
commit 38ad710aba
3 changed files with 23 additions and 1 deletions

View File

@ -11,6 +11,7 @@ from django.core.exceptions import (
ImproperlyConfigured,
ValidationError,
)
from django.core.validators import ProhibitNullCharactersValidator
from django.db.models.utils import AltersData
from django.forms.fields import ChoiceField, Field
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.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):
"""
Return ``limit_choices_to`` for this form field.
@ -1551,6 +1556,7 @@ class ModelChoiceField(ChoiceField):
def to_python(self, value):
if value in self.empty_values:
return None
self.validate_no_null_characters(value)
try:
key = self.to_field_name or "pk"
if isinstance(value, self.queryset.model):
@ -1631,6 +1637,7 @@ class ModelMultipleChoiceField(ModelChoiceField):
code="invalid_list",
)
for pk in value:
self.validate_no_null_characters(pk)
try:
self.queryset.filter(**{key: pk})
except (ValueError, TypeError):

View File

@ -7,7 +7,7 @@ from django.forms.widgets import CheckboxSelectMultiple
from django.template import Context, Template
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):
@ -79,6 +79,12 @@ class ModelChoiceFieldTests(TestCase):
self.assertEqual(f.clean(self.c1.slug), 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):
f = forms.ModelChoiceField(
Category.objects.filter(pk=self.c1.id), required=False

View File

@ -2227,6 +2227,15 @@ class ModelMultipleChoiceFieldTests(TestCase):
f = forms.ModelMultipleChoiceField(queryset=Writer.objects.all())
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):
"""
ModelMultipleChoiceField run given validators (#14144).