summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClaude Paroz <claude@2xlibre.net>2012-10-11 23:20:25 +0200
committerClaude Paroz <claude@2xlibre.net>2012-11-17 17:25:21 +0100
commit2a67374b51c5705d5c64a5d7117ad8552e98b4bb (patch)
treecbe0fd10c4d9a4b9d78d904c2f2d16110350ba68
parent9e7723f851dc6e4d5eea96ab808e1a4cdd4eabd7 (diff)
Fixed #19036 -- Fixed base64 uploads decoding
Thanks anthony at adsorbtion.org for the report, and johannesl for bringing the patch up-to-date.
-rw-r--r--django/http/multipartparser.py6
-rw-r--r--tests/regressiontests/file_uploads/tests.py13
2 files changed, 15 insertions, 4 deletions
diff --git a/django/http/multipartparser.py b/django/http/multipartparser.py
index 9413a1eabb..edf98f6e49 100644
--- a/django/http/multipartparser.py
+++ b/django/http/multipartparser.py
@@ -199,6 +199,12 @@ class MultiPartParser(object):
for chunk in field_stream:
if transfer_encoding == 'base64':
# We only special-case base64 transfer encoding
+ # We should always read base64 streams by multiple of 4
+ over_bytes = len(chunk) % 4
+ if over_bytes:
+ over_chunk = field_stream.read(4 - over_bytes)
+ chunk += over_chunk
+
try:
chunk = base64.b64decode(chunk)
except Exception as e:
diff --git a/tests/regressiontests/file_uploads/tests.py b/tests/regressiontests/file_uploads/tests.py
index 8fa140bc18..45e7342abd 100644
--- a/tests/regressiontests/file_uploads/tests.py
+++ b/tests/regressiontests/file_uploads/tests.py
@@ -74,15 +74,14 @@ class FileUploadTests(TestCase):
self.assertEqual(response.status_code, 200)
- def test_base64_upload(self):
- test_string = "This data will be transmitted base64-encoded."
+ def _test_base64_upload(self, content):
payload = client.FakePayload("\r\n".join([
'--' + client.BOUNDARY,
'Content-Disposition: form-data; name="file"; filename="test.txt"',
'Content-Type: application/octet-stream',
'Content-Transfer-Encoding: base64',
'',]))
- payload.write(b"\r\n" + base64.b64encode(force_bytes(test_string)) + b"\r\n")
+ payload.write(b"\r\n" + base64.b64encode(force_bytes(content)) + b"\r\n")
payload.write('--' + client.BOUNDARY + '--\r\n')
r = {
'CONTENT_LENGTH': len(payload),
@@ -94,7 +93,13 @@ class FileUploadTests(TestCase):
response = self.client.request(**r)
received = json.loads(response.content.decode('utf-8'))
- self.assertEqual(received['file'], test_string)
+ self.assertEqual(received['file'], content)
+
+ def test_base64_upload(self):
+ self._test_base64_upload("This data will be transmitted base64-encoded.")
+
+ def test_big_base64_upload(self):
+ self._test_base64_upload("Big data" * 68000) # > 512Kb
def test_unicode_file_name(self):
tdir = sys_tempfile.mkdtemp()