Fixed #28154 -- Prevented infinite loop in FileSystemStorage.save() when a broken symlink with the same name exists.

This commit is contained in:
Jacob Walls 2021-06-02 01:03:52 -04:00 committed by Mariusz Felisiak
parent d9cee3f5f2
commit ec2727efef
2 changed files with 12 additions and 1 deletions

View File

@ -316,7 +316,7 @@ class FileSystemStorage(Storage):
pass pass
def exists(self, name): def exists(self, name):
return os.path.exists(self.path(name)) return os.path.lexists(self.path(name))
def listdir(self, path): def listdir(self, path):
path = self.path(path) path = self.path(path)

View File

@ -28,6 +28,7 @@ from django.test import (
from django.test.utils import requires_tz_support from django.test.utils import requires_tz_support
from django.urls import NoReverseMatch, reverse_lazy from django.urls import NoReverseMatch, reverse_lazy
from django.utils import timezone from django.utils import timezone
from django.utils._os import symlinks_supported
from .models import ( from .models import (
Storage, callable_storage, temp_storage, temp_storage_location, Storage, callable_storage, temp_storage, temp_storage_location,
@ -297,6 +298,16 @@ class FileStorageTests(SimpleTestCase):
self.storage.delete('path/to/test.file') self.storage.delete('path/to/test.file')
@unittest.skipUnless(symlinks_supported(), 'Must be able to symlink to run this test.')
def test_file_save_broken_symlink(self):
"""A new path is created on save when a broken symlink is supplied."""
nonexistent_file_path = os.path.join(self.temp_dir, 'nonexistent.txt')
broken_symlink_path = os.path.join(self.temp_dir, 'symlink.txt')
os.symlink(nonexistent_file_path, broken_symlink_path)
f = ContentFile('some content')
f_name = self.storage.save(broken_symlink_path, f)
self.assertIs(os.path.exists(os.path.join(self.temp_dir, f_name)), True)
def test_save_doesnt_close(self): def test_save_doesnt_close(self):
with TemporaryUploadedFile('test', 'text/plain', 1, 'utf8') as file: with TemporaryUploadedFile('test', 'text/plain', 1, 'utf8') as file:
file.write(b'1') file.write(b'1')