Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Fixed #21033 -- Uploaded file's name truncates to 255 not in all cases #1548

Closed
wants to merge 1 commit into from

3 participants

homm Baptiste Mispelon Jacob Kaplan-Moss
homm

No description provided.

django/core/files/uploadedfile.py
... ... @@ -46,7 +46,7 @@ def _set_name(self, name):
46 46 # File names longer than 255 characters can cause problems on older OSes.
47 47 if len(name) > 255:
48 48 name, ext = os.path.splitext(name)
49   - name = name[:255 - len(ext)] + ext
  49 + name = name[:255 - len(ext)] + ext[:255]
2
Jacob Kaplan-Moss Owner

This doesn't actually work if name and ext are both too long:

>>> import os
>>> orig_name = 'name'*200 + '.' + 'ext'*200
>>> name, ext = os.path.splitext(orig_name)
>>> name = name[:255 - len(ext)] + ext[:255]
>>> len(name)
709
homm
homm added a note

Thank you. I fixed this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Baptiste Mispelon
Owner

Merged in 7008ed6 (with a few tweaks to the tests).

Thanks for your contribution!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Showing 1 unique commit by 1 author.

Sep 07, 2013
homm homm Fixed #21033 -- Uploaded file's name truncates to 255 not in all cases 509ba70
This page is out of date. Refresh to see the latest.
1  django/core/files/uploadedfile.py
@@ -46,6 +46,7 @@ def _set_name(self, name):
46 46 # File names longer than 255 characters can cause problems on older OSes.
47 47 if len(name) > 255:
48 48 name, ext = os.path.splitext(name)
  49 + ext = ext[:255]
49 50 name = name[:255 - len(ext)] + ext
50 51
51 52 self._name = name
37 tests/file_uploads/tests.py
@@ -167,16 +167,25 @@ def test_dangerous_file_names(self):
167 167
168 168 def test_filename_overflow(self):
169 169 """File names over 256 characters (dangerous on some platforms) get fixed up."""
170   - name = "%s.txt" % ("f"*500)
171   - payload = client.FakePayload("\r\n".join([
172   - '--' + client.BOUNDARY,
173   - 'Content-Disposition: form-data; name="file"; filename="%s"' % name,
174   - 'Content-Type: application/octet-stream',
175   - '',
176   - 'Oops.'
177   - '--' + client.BOUNDARY + '--',
178   - '',
179   - ]))
  170 + long_part = 'ab' * 130
  171 + cases = [
  172 + # name, filename, expected
  173 + ('plain', long_part, long_part[:255]),
  174 + ('long_name', long_part + ".txt", long_part[:251] + ".txt"),
  175 + ('long_ext', "file." + long_part, "." + long_part[:254]),
  176 + ('long_both', long_part + "." + long_part, "." + long_part[:254]),
  177 + ]
  178 + payload = client.FakePayload()
  179 + for name, filename, _ in cases:
  180 + payload.write("\r\n".join([
  181 + '--' + client.BOUNDARY,
  182 + 'Content-Disposition: form-data; name="{0}"; filename="{1}"',
  183 + 'Content-Type: application/octet-stream',
  184 + '',
  185 + 'Oops.',
  186 + ''
  187 + ]).format(name, filename))
  188 + payload.write('\r\n--' + client.BOUNDARY + '--\r\n')
180 189 r = {
181 190 'CONTENT_LENGTH': len(payload),
182 191 'CONTENT_TYPE': client.MULTIPART_CONTENT,
@@ -184,8 +193,12 @@ def test_filename_overflow(self):
184 193 'REQUEST_METHOD': 'POST',
185 194 'wsgi.input': payload,
186 195 }
187   - got = json.loads(self.client.request(**r).content.decode('utf-8'))
188   - self.assertTrue(len(got['file']) < 256, "Got a long file name (%s characters)." % len(got['file']))
  196 + result = json.loads(self.client.request(**r).content.decode('utf-8'))
  197 + for name, _, expected in cases:
  198 + got = result[name]
  199 + self.assertEqual(expected, got, 'Mismatch for {0}'.format(name))
  200 + self.assertTrue(len(got) < 256,
  201 + "Got a long file name (%s characters)." % len(got))
189 202
190 203 def test_content_type_extra(self):
191 204 """Uploaded files may have content type parameters available."""
1  tests/files/tests.py
@@ -131,7 +131,6 @@ def test_stringio(self):
131 131 self.assertEqual(f.read(), b'content')
132 132
133 133
134   -
135 134 class FileTests(unittest.TestCase):
136 135 def test_context_manager(self):
137 136 orig_file = tempfile.TemporaryFile()

Tip: You can add notes to lines in a file. Hover to the left of a line to make a note

Something went wrong with that request. Please try again.