diff --git a/django/http/multipartparser.py b/django/http/multipartparser.py index fd8fce8b4d4..33d8814241b 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 db9b915d352..5743344a517 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