mirror of https://github.com/django/django.git
Fixed #23397 -- Stripped whitespace from base64 during chunking
This insures the actual base64 content has a length a multiple of 4. Also added a test case for the failure.
This commit is contained in:
parent
22bfc45146
commit
e1424b2370
|
@ -206,14 +206,19 @@ 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
|
# We should always decode base64 chunks by multiple of 4,
|
||||||
over_bytes = len(chunk) % 4
|
# ignoring whitespace.
|
||||||
if over_bytes:
|
|
||||||
over_chunk = field_stream.read(4 - over_bytes)
|
stripped_chunk = b"".join(chunk.split())
|
||||||
chunk += over_chunk
|
|
||||||
|
remaining = len(stripped_chunk) % 4
|
||||||
|
while remaining != 0:
|
||||||
|
over_chunk = field_stream.read(4 - remaining)
|
||||||
|
stripped_chunk += b"".join(over_chunk.split())
|
||||||
|
remaining = len(stripped_chunk) % 4
|
||||||
|
|
||||||
try:
|
try:
|
||||||
chunk = base64.b64decode(chunk)
|
chunk = base64.b64decode(stripped_chunk)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
# Since this is only a chunk, any error is an unfixable error.
|
# Since this is only a chunk, any error is an unfixable error.
|
||||||
msg = "Could not decode base64 data: %r" % e
|
msg = "Could not decode base64 data: %r" % e
|
||||||
|
|
|
@ -77,14 +77,14 @@ class FileUploadTests(TestCase):
|
||||||
|
|
||||||
self.assertEqual(response.status_code, 200)
|
self.assertEqual(response.status_code, 200)
|
||||||
|
|
||||||
def _test_base64_upload(self, content):
|
def _test_base64_upload(self, content, encode=base64.b64encode):
|
||||||
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(content)) + b"\r\n")
|
payload.write(b"\r\n" + encode(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),
|
||||||
|
@ -104,6 +104,10 @@ class FileUploadTests(TestCase):
|
||||||
def test_big_base64_upload(self):
|
def test_big_base64_upload(self):
|
||||||
self._test_base64_upload("Big data" * 68000) # > 512Kb
|
self._test_base64_upload("Big data" * 68000) # > 512Kb
|
||||||
|
|
||||||
|
def test_big_base64_newlines_upload(self):
|
||||||
|
self._test_base64_upload(
|
||||||
|
"Big data" * 68000, encode=base64.encodestring)
|
||||||
|
|
||||||
def test_unicode_file_name(self):
|
def test_unicode_file_name(self):
|
||||||
tdir = sys_tempfile.mkdtemp()
|
tdir = sys_tempfile.mkdtemp()
|
||||||
self.addCleanup(shutil.rmtree, tdir, True)
|
self.addCleanup(shutil.rmtree, tdir, True)
|
||||||
|
|
Loading…
Reference in New Issue