Opened 8 years ago
Closed 3 years ago
#28154 closed Bug (fixed)
Infinite loop in collectstatic with broken symlinks
Reported by: | Matthew Somerville | Owned by: | Jacob Walls |
---|---|---|---|
Component: | File uploads/storage | Version: | dev |
Severity: | Normal | 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
If the static directory contains a broken symlink in place of a file that collectstatic wishes to copy*, then the code gets stuck in an infinite loop, because the os.open fails (O_CREAT | O_EXCL will fail if a symlink exists, even if it's to a non-existent file), but then get_available_name returns the same name (as it calls self.exists, which returns False for a broken symlink).
I guess two possibilities are:
- don't care about broken symlinks. Change the flags setting in django/core/files/storage.py to not include O_EXCL if
os.path.islink(full_path) and not os.path.exists(full_path)
. - do care, change os.path.exists in the
exists
function to use os.path.lexists instead.
I'm not sure which would be preferable to prevent this infinite loop.
*I came across this issue because collectstatic had been run both inside and outside a Vagrant box, so symlinks created inside the box did not exist when collectstatic was then run outside.
Change History (8)
comment:1 by , 8 years ago
Summary: | Infinite loop in collectstatic → Infinite loop in collectstatic with broken symlinks |
---|---|
Triage Stage: | Unreviewed → Accepted |
comment:2 by , 7 years ago
comment:3 by , 7 years ago
Which commit fixed it? Most likely a fix wouldn't qualify for a backport based on our supported versions policy.
comment:4 by , 7 years ago
Owner: | changed from | to
---|---|
Status: | new → assigned |
comment:5 by , 3 years ago
Owner: | changed from | to
---|---|
Version: | 1.11 → dev |
Decided to reproduce this on main. Still can.
I'm preparing a tiny patch using the second possibility from the ticket description: using os.path.lexists()
in FileSystemStorage.exists()
.
comment:6 by , 3 years ago
Component: | contrib.staticfiles → File uploads/storage |
---|---|
Has patch: | set |
I reproduced this outside of contrib.staticfiles by just providing a broken symlink to FileSystemStorage.save()
and never exiting a while
loop. I'm hoping this is a welcome root cause to look at.
comment:7 by , 3 years ago
Triage Stage: | Accepted → Ready for checkin |
---|
I think its fixed in master branch.
should we backport to 11.x ?