Yesterday, I opened a ticket around an issue I encountered as we upgraded to Django 5.1, where we started to see SuspiciousFileOperation
when the user uploaded a file with a name that contained a dot and which was too long for the corresponding FileField
. We increased our field max_length
as a quick fix, but we’re got a lot of FileField
s in our project, and every week there seems to be a new instance of this problem.
When the file name is too long, Django tries to truncate the file name as follows:
- Split the extension and the extensionless name (file root)
- Truncating the extensionless name
- Appending the extension back
That’s been part of Django for a long time and worked for single extensions.
In 5.1, a long standing bug was fixed to support multiple extensions (e.g. .tar.gz
). However, this had the side effect of treating anything after the first dot to be part of the extensions splitting, so john.doe - driving license.jpg
would get the extensions .doe - driving license.jpg
and file root would be john
.
The problem is that later on, in the Django method to find a name, we truncate the file root based on the total name length:
# Truncate file_root if max_length exceeded.
truncation = len(name) - max_length
if truncation > 0:
file_root = file_root[:-truncation]
In the earlier example it’s too much truncation, with a max length of e.g. 20, it gives a truncation of 9 (31 - 20), so when we do file_root[:-9]
, we get nothing left, which raises the seen exception.
The ticket was closed as won’t fix, with a comment that the suggested fix is too fragile and doesn’t belong in Django, which I 100% agree on.
However, I would like to discuss the possibilities to explore another way to fix this problem, as this has been working for a very long time, and it’s not uncommon to have a dot in the file name seems like a common use case.