From e65fea9292ffdeb9bb76062f6cb2a5ff514ae969 Mon Sep 17 00:00:00 2001
From: 007 <007gzs@gmail.com>
Date: Fri, 21 Feb 2020 13:25:22 +0800
Subject: [PATCH] Fixed #31293 -- Allowed MultiPartParser to handle
 double-quoted encoded headers.

---
 django/http/multipartparser.py |  6 ++---
 tests/file_uploads/tests.py    | 42 ++++++++++++++++++++++++++++++++++
 2 files changed, 45 insertions(+), 3 deletions(-)

diff --git a/django/http/multipartparser.py b/django/http/multipartparser.py
index fd8fce8b4d..33d8814241 100644
--- a/django/http/multipartparser.py
+++ b/django/http/multipartparser.py
@@ -664,12 +664,12 @@ def parse_header(line):
                 if p.count(b"'") == 2:
                     has_encoding = True
             value = p[i + 1:].strip()
-            if has_encoding:
-                encoding, lang, value = value.split(b"'")
-                value = unquote(value.decode(), encoding=encoding.decode())
             if len(value) >= 2 and value[:1] == value[-1:] == b'"':
                 value = value[1:-1]
                 value = value.replace(b'\\\\', b'\\').replace(b'\\"', b'"')
+            if has_encoding:
+                encoding, lang, value = value.split(b"'")
+                value = unquote(value.decode(), encoding=encoding.decode())
             pdict[name] = value
     return key, pdict
 
diff --git a/tests/file_uploads/tests.py b/tests/file_uploads/tests.py
index db9b915d35..5743344a51 100644
--- a/tests/file_uploads/tests.py
+++ b/tests/file_uploads/tests.py
@@ -162,6 +162,48 @@ class FileUploadTests(TestCase):
         response = self.client.request(**r)
         self.assertEqual(response.status_code, 200)
 
+    def test_unicode_file_name_rfc2231_with_double_quotes(self):
+        payload = client.FakePayload()
+        payload.write('\r\n'.join([
+            '--' + client.BOUNDARY,
+            'Content-Disposition: form-data; name="file_unicode"; '
+            'filename*="UTF-8\'\'%s"' % quote(UNICODE_FILENAME),
+            'Content-Type: application/octet-stream',
+            '',
+            'You got pwnd.\r\n',
+            '\r\n--' + client.BOUNDARY + '--\r\n',
+        ]))
+        r = {
+            'CONTENT_LENGTH': len(payload),
+            'CONTENT_TYPE': client.MULTIPART_CONTENT,
+            'PATH_INFO': '/unicode_name/',
+            'REQUEST_METHOD': 'POST',
+            'wsgi.input': payload,
+        }
+        response = self.client.request(**r)
+        self.assertEqual(response.status_code, 200)
+
+    def test_unicode_name_rfc2231_with_double_quotes(self):
+        payload = client.FakePayload()
+        payload.write('\r\n'.join([
+            '--' + client.BOUNDARY,
+            'Content-Disposition: form-data; name*="UTF-8\'\'file_unicode"; '
+            'filename*="UTF-8\'\'%s"' % quote(UNICODE_FILENAME),
+            'Content-Type: application/octet-stream',
+            '',
+            'You got pwnd.\r\n',
+            '\r\n--' + client.BOUNDARY + '--\r\n'
+        ]))
+        r = {
+            'CONTENT_LENGTH': len(payload),
+            'CONTENT_TYPE': client.MULTIPART_CONTENT,
+            'PATH_INFO': '/unicode_name/',
+            'REQUEST_METHOD': 'POST',
+            'wsgi.input': payload,
+        }
+        response = self.client.request(**r)
+        self.assertEqual(response.status_code, 200)
+
     def test_blank_filenames(self):
         """
         Receiving file upload when filename is blank (before and after