Commit 18e79f14 authored by Russell Keith-Magee's avatar Russell Keith-Magee
Browse files

Fixed #20486 -- Ensure that file_move_safe raises an error if the destination already exists.

Thanks to kux for the report, and Russ Webber for the patch.
parent 3671e7e3
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -608,6 +608,7 @@ answer newbie questions, and generally made Django that much better:
    Filip Wasilewski <filip.wasilewski@gmail.com>
    Dan Watson <http://danwatson.net/>
    Joel Watts <joel@joelwatts.com>
    Russ Webber
    Lakin Wecker <lakin@structuredabstraction.com>
    Chris Wesseling <Chris.Wesseling@cwi.nl>
    Benjamin Wohlwend <piquadrat@gmail.com>
+4 −0
Original line number Diff line number Diff line
@@ -51,6 +51,10 @@ def file_move_safe(old_file_name, new_file_name, chunk_size = 1024*64, allow_ove
        return

    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)
        return
    except OSError:
+14 −0
Original line number Diff line number Diff line
from __future__ import absolute_import

import os
import gzip
import shutil
import tempfile

from django.core.cache import cache
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.uploadedfile import SimpleUploadedFile
from django.test import TestCase
@@ -146,3 +148,15 @@ class FileTests(unittest.TestCase):
        file = SimpleUploadedFile("mode_test.txt", b"content")
        self.assertFalse(hasattr(file, 'mode'))
        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))