Opened 3 months ago
Last modified 2 months 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 )
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.