#9610 closed (fixed)
File upload duplicate filename check mechanism fail
| Reported by: | fadlytabrani | Owned by: | fadlytabrani |
|---|---|---|---|
| Component: | File uploads/storage | Version: | 1.0 |
| Severity: | Keywords: | ||
| Cc: | Triage Stage: | Ready for checkin | |
| Has patch: | yes | Needs documentation: | no |
| Needs tests: | no | Patch needs improvement: | no |
| Easy pickings: | no | UI/UX: | no |
Description
The file upload duplicate filename check mechanism will fail if the upload directory contains a dot and when the filename does not.
django.core.files.storage:Storage
def get_available_name(self, name):
"""
Returns a filename that's free on the target storage system, and
available for new content to be written to.
"""
# If the filename already exists, keep adding an underscore to the name
# of the file until the filename doesn't exist.
while self.exists(name):
try:
dot_index = name.rindex('.')
except ValueError: # filename has no dot
name += '_'
else:
name = name[:dot_index] + '_' + name[dot_index:]
return name
# Failure example, uploading duplicate file "testlog" will create new directory upload_.10122008
# Correct result would be "testlog" would be uploaded with the filename testlog_
get_available_name("c:\\django\\media\\upload.10122008\\testlog")
Using os.path would solve the problem
def get_available_name(self, name):
while self.exists(name):
dname, fname = os.path.split(name)
try:
dot_index = fname.rindex('.')
except ValueError:
fname += '_'
else:
fname = fname[:dot_index] + '_' + fname[dot_index:]
return os.path.join(dname, fname)
Attachments (3)
Change History (18)
comment:1 by , 17 years ago
comment:2 by , 17 years ago
Little improvement:
def get_available_namex(self, name):
dir_name, file_name = os.path.split(name)
while self.exists(name):
try:
dot_index = file_name.rindex('.')
except ValueError:
file_name += '_'
else:
file_name = file_name[:dot_index] + '_' + file_name[dot_index:]
name = os.path.join(dir_name, file_name)
return name
by , 17 years ago
| Attachment: | storage.py.patch added |
|---|
comment:3 by , 17 years ago
| Owner: | changed from to |
|---|---|
| Status: | new → assigned |
Patch attached
The line :
dir_name, file_name = os.path.split(name)
should be within the while loop to acommodate checking more than once
def get_available_name(self, name):
while self.exists(name):
dir_name, file_name = os.path.split(name)
try:
dot_index = file_name.rindex('.')
except ValueError:
file_name += '_'
else:
file_name = file_name[:dot_index] + '_' + file_name[dot_index:]
name = os.path.join(dir_name, file_name)
return name
follow-up: 7 comment:4 by , 17 years ago
| Triage Stage: | Unreviewed → Ready for checkin |
|---|
comment:5 by , 17 years ago
| Triage Stage: | Ready for checkin → Design decision needed |
|---|
comment:6 by , 17 years ago
| Resolution: | → worksforme |
|---|---|
| Status: | assigned → closed |
| Triage Stage: | Design decision needed → Unreviewed |
follow-up: 8 comment:7 by , 17 years ago
| Patch needs improvement: | set |
|---|
Replying to fadlytabrani:
The line should be within the while loop to acommodate checking more than once
Nope. dir_name never changes and it should be calculated once. But your version calls unneeded split every iteration. Just check in debugger (or something like that) if you unsure.
by , 17 years ago
| Attachment: | storage.py.2.patch added |
|---|
comment:8 by , 17 years ago
Replying to dc:
Replying to fadlytabrani:
The line should be within the while loop to acommodate checking more than once
Nope. dir_name never changes and it should be calculated once. But your version calls unneeded split every iteration. Just check in debugger (or something like that) if you unsure.
Thanks dc, you're correct :) I missed that one
Have uploaded correct path
comment:9 by , 17 years ago
| Needs tests: | set |
|---|---|
| Patch needs improvement: | unset |
comment:10 by , 17 years ago
| Resolution: | worksforme |
|---|---|
| Status: | closed → reopened |
Still a bug which must be fixed.
comment:12 by , 17 years ago
| milestone: | → 1.1 |
|---|---|
| Triage Stage: | Unreviewed → Accepted |
by , 17 years ago
Added tests, and updated the patch to unified diff format.
comment:13 by , 17 years ago
| Needs tests: | unset |
|---|---|
| Triage Stage: | Accepted → Ready for checkin |
comment:14 by , 17 years ago
| Resolution: | → fixed |
|---|---|
| Status: | reopened → closed |
Initial submitted fix doesn't work, this does
def get_available_namex(self, name): while self.exists(name): dname, fname = os.path.split(name) try: dot_index = fname.rindex('.') except ValueError: fname += '_' else: fname = fname[:dot_index] + '_' + fname[dot_index:] name = os.path.join(dname, fname) return name