Fixed #19036 -- Fixed base64 uploads decoding

Thanks anthony at adsorbtion.org for the report, and johannesl for
bringing the patch up-to-date.
This commit is contained in:
Claude Paroz 2012-10-11 23:20:25 +02:00
parent 9e7723f851
commit 2a67374b51
2 changed files with 15 additions and 4 deletions

View File

@ -199,6 +199,12 @@ class MultiPartParser(object):
for chunk in field_stream: for chunk in field_stream:
if transfer_encoding == 'base64': if transfer_encoding == 'base64':
# We only special-case base64 transfer encoding # 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: try:
chunk = base64.b64decode(chunk) chunk = base64.b64decode(chunk)
except Exception as e: except Exception as e:

View File

@ -74,15 +74,14 @@ class FileUploadTests(TestCase):
self.assertEqual(response.status_code, 200) self.assertEqual(response.status_code, 200)
def test_base64_upload(self): def _test_base64_upload(self, content):
test_string = "This data will be transmitted base64-encoded."
payload = client.FakePayload("\r\n".join([ payload = client.FakePayload("\r\n".join([
'--' + client.BOUNDARY, '--' + client.BOUNDARY,
'Content-Disposition: form-data; name="file"; filename="test.txt"', 'Content-Disposition: form-data; name="file"; filename="test.txt"',
'Content-Type: application/octet-stream', 'Content-Type: application/octet-stream',
'Content-Transfer-Encoding: base64', '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') payload.write('--' + client.BOUNDARY + '--\r\n')
r = { r = {
'CONTENT_LENGTH': len(payload), 'CONTENT_LENGTH': len(payload),
@ -94,7 +93,13 @@ class FileUploadTests(TestCase):
response = self.client.request(**r) response = self.client.request(**r)
received = json.loads(response.content.decode('utf-8')) 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): def test_unicode_file_name(self):
tdir = sys_tempfile.mkdtemp() tdir = sys_tempfile.mkdtemp()