Skip to content

Commit

Permalink
Fixed #20486 -- Ensure that file_move_safe raises an error if the des…
Browse files Browse the repository at this point in the history
…tination already exists.

Thanks to kux for the report, and Russ Webber for the patch.
  • Loading branch information
freakboy3742 committed Jun 20, 2013
1 parent 3671e7e commit 18e79f1
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 0 deletions.
1 change: 1 addition & 0 deletions AUTHORS
Expand Up @@ -608,6 +608,7 @@ answer newbie questions, and generally made Django that much better:
Filip Wasilewski <filip.wasilewski@gmail.com> Filip Wasilewski <filip.wasilewski@gmail.com>
Dan Watson <http://danwatson.net/> Dan Watson <http://danwatson.net/>
Joel Watts <joel@joelwatts.com> Joel Watts <joel@joelwatts.com>
Russ Webber
Lakin Wecker <lakin@structuredabstraction.com> Lakin Wecker <lakin@structuredabstraction.com>
Chris Wesseling <Chris.Wesseling@cwi.nl> Chris Wesseling <Chris.Wesseling@cwi.nl>
Benjamin Wohlwend <piquadrat@gmail.com> Benjamin Wohlwend <piquadrat@gmail.com>
Expand Down
4 changes: 4 additions & 0 deletions django/core/files/move.py
Expand Up @@ -51,6 +51,10 @@ def file_move_safe(old_file_name, new_file_name, chunk_size = 1024*64, allow_ove
return return


try: try:
# If the destination file exists and allow_overwrite is False then raise an IOError
if not allow_overwrite and os.access(new_file_name, os.F_OK):
raise IOError("Destination file %s exists and allow_overwrite is False" % new_file_name)

os.rename(old_file_name, new_file_name) os.rename(old_file_name, new_file_name)
return return
except OSError: except OSError:
Expand Down
14 changes: 14 additions & 0 deletions tests/files/tests.py
@@ -1,11 +1,13 @@
from __future__ import absolute_import from __future__ import absolute_import


import os
import gzip import gzip
import shutil import shutil
import tempfile import tempfile


from django.core.cache import cache from django.core.cache import cache
from django.core.files import File from django.core.files import File
from django.core.files.move import file_move_safe
from django.core.files.base import ContentFile from django.core.files.base import ContentFile
from django.core.files.uploadedfile import SimpleUploadedFile from django.core.files.uploadedfile import SimpleUploadedFile
from django.test import TestCase from django.test import TestCase
Expand Down Expand Up @@ -146,3 +148,15 @@ def test_file_mode(self):
file = SimpleUploadedFile("mode_test.txt", b"content") file = SimpleUploadedFile("mode_test.txt", b"content")
self.assertFalse(hasattr(file, 'mode')) self.assertFalse(hasattr(file, 'mode'))
g = gzip.GzipFile(fileobj=file) g = gzip.GzipFile(fileobj=file)


class FileMoveSafeTests(unittest.TestCase):
def test_file_move_overwrite(self):
handle_a, self.file_a = tempfile.mkstemp(dir=os.environ['DJANGO_TEST_TEMP_DIR'])
handle_b, self.file_b = tempfile.mkstemp(dir=os.environ['DJANGO_TEST_TEMP_DIR'])

# file_move_safe should raise an IOError exception if destination file exists and allow_overwrite is False
self.assertRaises(IOError, lambda: file_move_safe(self.file_a, self.file_b, allow_overwrite=False))

# should allow it and continue on if allow_overwrite is True
self.assertIsNone(file_move_safe(self.file_a, self.file_b, allow_overwrite=True))

0 comments on commit 18e79f1

Please sign in to comment.