validators: work around lack of NULL char check in forms.CharField (#46625)

This commit is contained in:
Benjamin Dauvergne 2020-10-06 11:58:49 +02:00
parent d3c962e095
commit 7a3be23b0d
2 changed files with 46 additions and 0 deletions

View File

@ -14,4 +14,24 @@
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import django
default_app_config = 'authentic2.app.Authentic2Config'
if django.VERSION < (2,):
from . import validators
from django.forms import fields
import rest_framework.fields
# query-string and form parameters used to query database charfield must be checked for NULL characters
# https://code.djangoproject.com/ticket/30064
if not getattr(fields.CharField, 'a2_workaround', False):
CharField_old__init__ = fields.CharField.__init__
def CharField_new_init__(self, *args, **kwargs):
CharField_old__init__(self, *args, **kwargs)
self.validators.append(validators.ProhibitNullCharactersValidator())
fields.CharField.__init__ = CharField_new_init__
fields.CharField.a2_workaround = True
rest_framework.fields.ProhibitNullCharactersValidator = validators.ProhibitNullCharactersValidator

View File

@ -18,6 +18,8 @@ from __future__ import unicode_literals
import smtplib
import django
from django.utils.deconstruct import deconstructible
from django.utils.translation import ugettext_lazy as _
from django.core.exceptions import ValidationError
from django.core.validators import RegexValidator, EmailValidator as DjangoEmailValidator
@ -97,3 +99,27 @@ class UsernameValidator(RegexValidator):
def __init__(self, *args, **kwargs):
self.regex = app_settings.A2_REGISTRATION_FORM_USERNAME_REGEX
super(UsernameValidator, self).__init__(*args, **kwargs)
@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
)