-
-
Notifications
You must be signed in to change notification settings - Fork 32.8k
Fixed #35673 -- Enhanced ExceptionReporter
to handle GET and FILES parameters
#19702
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you, this is a great start ⭐
django/views/debug.py
Outdated
try: | ||
c["request_FILES_items"] = self.request.FILES.items() | ||
except TooManyFilesSent: | ||
c["request_FILES_items"] = [ | ||
( | ||
"<could not parse>", | ||
"Number of FILES parameters exceeded " | ||
"DATA_UPLOAD_MAX_NUMBER_FILES", | ||
) | ||
] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
try: | |
c["request_FILES_items"] = self.request.FILES.items() | |
except TooManyFilesSent: | |
c["request_FILES_items"] = [ | |
( | |
"<could not parse>", | |
"Number of FILES parameters exceeded " | |
"DATA_UPLOAD_MAX_NUMBER_FILES", | |
) | |
] | |
c["request_FILES_items"] = self.request.FILES.items() |
Note that this can be reverted without any test failures
We might also want to test for (and possibly handle) too many POST parameters
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for the updates 👍 this is getting closer ⭐
c["request_FILES_items"] = self.request.FILES.items() | ||
try: | ||
c["request_GET_items"] = self.request.GET.items() | ||
c["request_GET_error"] = None |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
c["request_GET_error"] = None |
We can omit this
@override_settings(DATA_UPLOAD_MAX_NUMBER_FIELDS=1) | ||
def test_max_number_of_fields_exceeded(self): | ||
with self.assertLogs("django.request", "ERROR"): | ||
response = self.client.get("/raises500/", {"a": "1", "b": "2"}) | ||
|
||
self.assertEqual(response.status_code, 500) | ||
self.assertContains(response, '<div class="context" id="', status_code=500) | ||
self.assertContains(response, "Exception", status_code=500) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@override_settings(DATA_UPLOAD_MAX_NUMBER_FIELDS=1) | |
def test_max_number_of_fields_exceeded(self): | |
with self.assertLogs("django.request", "ERROR"): | |
response = self.client.get("/raises500/", {"a": "1", "b": "2"}) | |
self.assertEqual(response.status_code, 500) | |
self.assertContains(response, '<div class="context" id="', status_code=500) | |
self.assertContains(response, "Exception", status_code=500) | |
@override_settings(DATA_UPLOAD_MAX_NUMBER_FIELDS=1) | |
def test_max_number_of_fields_exceeded_get(self): | |
with self.assertLogs("django.request", "ERROR"): | |
response = self.client.get("/raises500/", {"a": "1", "b": "2"}) | |
self.assertEqual(response.status_code, 500) | |
self.assertContains( | |
response, | |
"The number of GET/POST parameters exceeded " | |
"settings.DATA_UPLOAD_MAX_NUMBER_FIELDS.", | |
status_code=500 | |
) | |
@override_settings(DATA_UPLOAD_MAX_NUMBER_FILES=1) | |
def test_max_number_of_fields_exceeded_files(self): | |
data = { | |
"file_data.txt": SimpleUploadedFile("file_data.txt", b"data"), | |
"file_data_2.txt": SimpleUploadedFile("file_data_2.txt", b"data2"), | |
} | |
with self.assertLogs("django.request", "ERROR"): | |
response = self.client.post("/raises/", data) | |
self.assertContains( | |
response, | |
"The number of files exceeded " | |
"settings.DATA_UPLOAD_MAX_NUMBER_FILES.", | |
status_code=500 | |
) |
You're missing a test for the files case
I have written an example test here but this currently fails because there is not error handling in accessing POST data:
File "/path-to-django/django/views/debug.py", line 398, in get_traceback_data
self.filter.get_post_parameters(self.request).items()
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/path-to-django/django/views/debug.py", line 225, in get_post_parameters
return request.POST
^^^^^^^^^^^^
This needs similar error handling
Trac ticket number
ticket-35673
Branch description
Problem:
Django's ExceptionReporter crashes with infinite loops when handling requests that exceed
DATA_UPLOAD_MAX_NUMBER_FIELDS
limits, resulting in blank 500 error pages instead of useful debug information.Solution:
Implemented
SafeExceptionRequest
wrapper class that safely handlesrequest.GET
andrequest.FILES
access by catchingTooManyFieldsSent
/TooManyFilesSent
exceptions and returning empty collections with error indicators.Checklist
main
branch.