I guess two possibilities are:
1. 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)`.
2. 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.
--
Ticket URL: <https://code.djangoproject.com/ticket/28154>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
* stage: Unreviewed => Accepted
--
Ticket URL: <https://code.djangoproject.com/ticket/28154#comment:1>
Comment (by KwonHan Bae):
I think its fixed in master branch.
should we backport to 11.x ?
--
Ticket URL: <https://code.djangoproject.com/ticket/28154#comment:2>
Comment (by Tim Graham):
Which commit fixed it? Most likely a fix wouldn't qualify for a backport
based on our [https://docs.djangoproject.com/en/dev/internals/release-
process/#supported-versions supported versions policy].
--
Ticket URL: <https://code.djangoproject.com/ticket/28154#comment:3>
* status: new => assigned
* owner: nobody => ChillarAnand
--
Ticket URL: <https://code.djangoproject.com/ticket/28154#comment:4>
* owner: ChillarAnand => Jacob Walls
* version: 1.11 => dev
Comment:
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()`.
--
Ticket URL: <https://code.djangoproject.com/ticket/28154#comment:5>
* has_patch: 0 => 1
* component: contrib.staticfiles => File uploads/storage
Comment:
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.
[https://github.com/django/django/pull/14474 PR]
--
Ticket URL: <https://code.djangoproject.com/ticket/28154#comment:6>
* stage: Accepted => Ready for checkin
--
Ticket URL: <https://code.djangoproject.com/ticket/28154#comment:7>
* status: assigned => closed
* resolution: => fixed
Comment:
In [changeset:"ec2727efef605437eb572d51ca9afbb3a60eda40" ec2727ef]:
{{{
#!CommitTicketReference repository=""
revision="ec2727efef605437eb572d51ca9afbb3a60eda40"
Fixed #28154 -- Prevented infinite loop in FileSystemStorage.save() when a
broken symlink with the same name exists.
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/28154#comment:8>