瀏覽代碼

Fixed #27820 -- Fixed RequestDataTooBig/TooManyFieldsSent crash.

amalia 8 年之前
父節點
當前提交
2f10216f84
共有 3 個文件被更改,包括 39 次插入1 次删除
  1. 9 1
      django/core/handlers/exception.py
  2. 3 0
      docs/releases/1.10.6.txt
  3. 27 0
      tests/handlers/test_exception.py

+ 9 - 1
django/core/handlers/exception.py

@@ -4,7 +4,10 @@ from functools import wraps
 
 from django.conf import settings
 from django.core import signals
-from django.core.exceptions import PermissionDenied, SuspiciousOperation
+from django.core.exceptions import (
+    PermissionDenied, RequestDataTooBig, SuspiciousOperation,
+    TooManyFieldsSent,
+)
 from django.http import Http404
 from django.http.multipartparser import MultiPartParserError
 from django.urls import get_resolver, get_urlconf
@@ -59,6 +62,11 @@ def response_for_exception(request, exc):
         response = get_exception_response(request, get_resolver(get_urlconf()), 400, exc)
 
     elif isinstance(exc, SuspiciousOperation):
+        if isinstance(exc, (RequestDataTooBig, TooManyFieldsSent)):
+            # POST data can't be accessed again, otherwise the original
+            # exception would be raised.
+            request._mark_post_parse_error()
+
         # The request logger receives events for any problematic request
         # The security logger receives events for all SuspiciousOperations
         security_logger = logging.getLogger('django.security.%s' % exc.__class__.__name__)

+ 3 - 0
docs/releases/1.10.6.txt

@@ -11,3 +11,6 @@ Bugfixes
 
 * Fixed ``ClearableFileInput``’s "Clear" checkbox on model form fields where
   the model field has a ``default`` (:ticket:`27805`).
+
+* Fixed ``RequestDataTooBig`` and ``TooManyFieldsSent`` exceptions crashing
+  rather than generating a bad request response (:ticket:`27820`).

+ 27 - 0
tests/handlers/test_exception.py

@@ -0,0 +1,27 @@
+from django.core.handlers.wsgi import WSGIHandler
+from django.test import SimpleTestCase, override_settings
+from django.test.client import FakePayload
+
+
+class ExceptionHandlerTests(SimpleTestCase):
+
+    def get_suspicious_environ(self):
+        payload = FakePayload('a=1&a=2;a=3\r\n')
+        return {
+            'REQUEST_METHOD': 'POST',
+            'CONTENT_TYPE': 'application/x-www-form-urlencoded',
+            'CONTENT_LENGTH': len(payload),
+            'wsgi.input': payload,
+            'SERVER_NAME': 'test',
+            'SERVER_PORT': '8000',
+        }
+
+    @override_settings(DATA_UPLOAD_MAX_MEMORY_SIZE=12)
+    def test_data_upload_max_memory_size_exceeded(self):
+        response = WSGIHandler()(self.get_suspicious_environ(), lambda *a, **k: None)
+        self.assertEqual(response.status_code, 400)
+
+    @override_settings(DATA_UPLOAD_MAX_NUMBER_FIELDS=2)
+    def test_data_upload_max_number_fields_exceeded(self):
+        response = WSGIHandler()(self.get_suspicious_environ(), lambda *a, **k: None)
+        self.assertEqual(response.status_code, 400)