#30064: Admin search with a null character crashes with "A string literal cannot
contain NUL (0x00) characters." on PostgreSQL
-------------------------------+------------------------------------
     Reporter:  kenichi-cc     |                    Owner:  nobody
         Type:  Bug            |                   Status:  new
    Component:  contrib.admin  |                  Version:  2.1
     Severity:  Normal         |               Resolution:
     Keywords:                 |             Triage Stage:  Accepted
    Has patch:  1              |      Needs documentation:  0
  Needs tests:  0              |  Patch needs improvement:  1
Easy pickings:  0              |                    UI/UX:  0
-------------------------------+------------------------------------

Comment (by Can Sarıgöl):

 {{{
 diff --git a/django/contrib/admin/views/main.py
 b/django/contrib/admin/views/main.py
 index 298e18c57e..4724ccfa96 100644
 --- a/django/contrib/admin/views/main.py
 +++ b/django/contrib/admin/views/main.py
 @@ -1,6 +1,6 @@
  from collections import OrderedDict
  from datetime import datetime, timedelta
 -
 +from django import forms
  from django.conf import settings
  from django.contrib.admin import FieldListFilter
  from django.contrib.admin.exceptions import (
 @@ -35,6 +35,33 @@ IGNORED_PARAMS = (
      ALL_VAR, ORDER_VAR, ORDER_TYPE_VAR, SEARCH_VAR, IS_POPUP_VAR,
 TO_FIELD_VAR)


 +class ChangeListForm(forms.Form):
 +
 +    def __init__(self, *args, **kwargs):
 +        super(ChangeListForm, self).__init__(*args, **kwargs)
 +        for var in {SEARCH_VAR, PAGE_VAR, TO_FIELD_VAR}:
 +            field = forms.CharField()
 +            field.required = False
 +            self.fields[var] = field
 +
 +    def clean(self):
 +        query = self.data.get(SEARCH_VAR)
 +        if '\x00' in query:
 +            raise forms.ValidationError('Null characters are not
 allowed.')
 +
 +        page_num = self.cleaned_data.get(PAGE_VAR)
 +        if not page_num:
 +            page_num = 0
 +            self.cleaned_data[PAGE_VAR]  = page_num
 +
 +        to_field = self.cleaned_data.get(TO_FIELD_VAR)
 +        if to_field and not model_admin.to_field_allowed(request,
 to_field):
 +            raise DisallowedModelAdminToField("The field %s cannot be
 referenced." % to_field)
 +
 +        return self.cleaned_data
 +
 +
 +
  class ChangeList:
      def __init__(self, request, model, list_display, list_display_links,
                   list_filter, date_hierarchy, search_fields,
 list_select_related,
 @@ -46,7 +73,6 @@ class ChangeList:
          self.list_display = list_display
          self.list_display_links = list_display_links
          self.list_filter = list_filter
 -        self.has_filters = None
          self.date_hierarchy = date_hierarchy
          self.search_fields = search_fields
          self.list_select_related = list_select_related
 @@ -57,16 +83,18 @@ class ChangeList:
          self.sortable_by = sortable_by

          # Get search parameters from the query string.
 -        try:
 -            self.page_num = int(request.GET.get(PAGE_VAR, 0))
 -        except ValueError:
 -            self.page_num = 0
 +        change_list_form = ChangeListForm(request.GET)
 +        if not change_list_form.is_valid():
 +            raise forms.ValidationError(change_list_form.errors)
 +
 +        change_list_form_cleaned = change_list_form.clean()
 +        self.page_num = change_list_form_cleaned.get(PAGE_VAR)
 +        self.query = change_list_form_cleaned.get(SEARCH_VAR)
 +        self.to_field = change_list_form_cleaned.get(TO_FIELD_VAR)
 +
          self.show_all = ALL_VAR in request.GET
          self.is_popup = IS_POPUP_VAR in request.GET
 -        to_field = request.GET.get(TO_FIELD_VAR)
 -        if to_field and not model_admin.to_field_allowed(request,
 to_field):
 -            raise DisallowedModelAdminToField("The field %s cannot be
 referenced." % to_field)
 -        self.to_field = to_field
 +
          self.params = dict(request.GET.items())
          if PAGE_VAR in self.params:
              del self.params[PAGE_VAR]
 @@ -77,7 +105,6 @@ class ChangeList:
              self.list_editable = ()
          else:
              self.list_editable = list_editable
 -        self.query = request.GET.get(SEARCH_VAR, '')
          self.queryset = self.get_queryset(request)
          self.get_results(request)
          if self.is_popup:
 @@ -95,6 +122,7 @@ class ChangeList:
 }}}

-- 
Ticket URL: <https://code.djangoproject.com/ticket/30064#comment:8>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/068.953343ecb49ca999256e21a58e5af281%40djangoproject.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to