#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.