Opened 6 weeks ago

Last modified 5 weeks ago

#35818 closed Bug

Failing to save file with long names containing dots — at Version 1

Reported by: Bruno Alla Owned by:
Component: File uploads/storage Version: 5.1
Severity: Normal Keywords:
Cc: Triage Stage: Unreviewed
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description (last modified by Bruno Alla)

This started to happen as we updated to Djanho 5.1. We started seeing some SuspiciousFileOperation errors when our users were trying to upload long file names and wasn't initially clear why it started to happen only recently.

After further investigation, it's only a problem when the file name contains a "." in the middle name, and which point the truncation logic trims too many characters, and end up with no base name on this line: https://github.com/django/django/blob/6bedb102e9708c6183caa51330f9bdeddf944d6a/django/core/files/storage/base.py#L106-L111

Here is a minimal reproduction:

# models.py
class Document(models.Model):
    file = models.FileField(upload_to="documents/")


# tests.py
class TestDocument(TestCase):
    def test_save_file(self):
        file_name = "this.is.a.very.l" + "o" * 100 + ".txt"
        Document.objects.create(file=SimpleUploadedFile(name=file_name, content=b"test"))

I created a GitHub repo based off startproject with that code to make it easier to run: https://github.com/browniebroke/django-suspicious-filename-too-long-with-dot

The test passes on Django 5.0 but fails on Django 5.1 with the following exception:

django.core.exceptions.SuspiciousFileOperation: Storage can not find an available filename for "documents/this_d01Yq4J.is.a.very.loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo.txt". Please make sure that the corresponding file field allows sufficient "max_length".

From what I can tell, the bug starts on line 87, when we try to get the file extension: https://github.com/django/django/blob/6bedb102e9708c6183caa51330f9bdeddf944d6a/django/core/files/storage/base.py#L87

On the next line, the extension is removed from the name to get the file root, which removes a lot more characters than expected, as the extension starts at the first ".", instead of the last one.

Change History (1)

comment:1 by Bruno Alla, 6 weeks ago

Description: modified (diff)
Note: See TracTickets for help on using tickets.
Back to Top