2
0
Эх сурвалжийг харах

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>
Alexander Lötvall 9 сар өмнө
parent
commit
38ad710aba

+ 7 - 0
django/forms/models.py

@@ -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):

+ 7 - 1
tests/model_forms/test_modelchoicefield.py

@@ -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

+ 9 - 0
tests/model_forms/tests.py

@@ -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).