Skip to content

Commit

Permalink
Fixed #21033 -- Fixed uploaded filenames not always being truncated t…
Browse files Browse the repository at this point in the history
…o 255 characters
  • Loading branch information
homm authored and bmispelon committed Sep 9, 2013
1 parent d6e222f commit 7008ed6
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 13 deletions.
1 change: 1 addition & 0 deletions django/core/files/uploadedfile.py
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ def _set_name(self, name):
# File names longer than 255 characters can cause problems on older OSes. # File names longer than 255 characters can cause problems on older OSes.
if len(name) > 255: if len(name) > 255:
name, ext = os.path.splitext(name) name, ext = os.path.splitext(name)
ext = ext[:255]
name = name[:255 - len(ext)] + ext name = name[:255 - len(ext)] + ext


self._name = name self._name = name
Expand Down
38 changes: 26 additions & 12 deletions tests/file_uploads/tests.py
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -167,25 +167,39 @@ def test_dangerous_file_names(self):


def test_filename_overflow(self): def test_filename_overflow(self):
"""File names over 256 characters (dangerous on some platforms) get fixed up.""" """File names over 256 characters (dangerous on some platforms) get fixed up."""
name = "%s.txt" % ("f"*500) long_str = 'f' * 300
payload = client.FakePayload("\r\n".join([ cases = [
'--' + client.BOUNDARY, # field name, filename, expected
'Content-Disposition: form-data; name="file"; filename="%s"' % name, ('long_filename', '%s.txt' % long_str, '%s.txt' % long_str[:251]),
'Content-Type: application/octet-stream', ('long_extension', 'foo.%s' % long_str, '.%s' % long_str[:254]),
'', ('no_extension', long_str, long_str[:255]),
'Oops.' ('no_filename', '.%s' % long_str, '.%s' % long_str[:254]),
'--' + client.BOUNDARY + '--', ('long_everything', '%s.%s' % (long_str, long_str), '.%s' % long_str[:254]),
'', ]
])) payload = client.FakePayload()
for name, filename, _ in cases:
payload.write("\r\n".join([
'--' + client.BOUNDARY,
'Content-Disposition: form-data; name="{0}"; filename="{1}"',
'Content-Type: application/octet-stream',
'',
'Oops.',
''
]).format(name, filename))
payload.write('\r\n--' + client.BOUNDARY + '--\r\n')
r = { r = {
'CONTENT_LENGTH': len(payload), 'CONTENT_LENGTH': len(payload),
'CONTENT_TYPE': client.MULTIPART_CONTENT, 'CONTENT_TYPE': client.MULTIPART_CONTENT,
'PATH_INFO': "/file_uploads/echo/", 'PATH_INFO': "/file_uploads/echo/",
'REQUEST_METHOD': 'POST', 'REQUEST_METHOD': 'POST',
'wsgi.input': payload, 'wsgi.input': payload,
} }
got = json.loads(self.client.request(**r).content.decode('utf-8')) result = json.loads(self.client.request(**r).content.decode('utf-8'))
self.assertTrue(len(got['file']) < 256, "Got a long file name (%s characters)." % len(got['file'])) for name, _, expected in cases:
got = result[name]
self.assertEqual(expected, got, 'Mismatch for {0}'.format(name))
self.assertTrue(len(got) < 256,
"Got a long file name (%s characters)." % len(got))


def test_content_type_extra(self): def test_content_type_extra(self):
"""Uploaded files may have content type parameters available.""" """Uploaded files may have content type parameters available."""
Expand Down
1 change: 0 additions & 1 deletion tests/files/tests.py
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -132,7 +132,6 @@ def test_stringio(self):
self.assertEqual(f.read(), b'content') self.assertEqual(f.read(), b'content')





class FileTests(unittest.TestCase): class FileTests(unittest.TestCase):
def test_context_manager(self): def test_context_manager(self):
orig_file = tempfile.TemporaryFile() orig_file = tempfile.TemporaryFile()
Expand Down

0 comments on commit 7008ed6

Please sign in to comment.