Ticket #8593: 8593.diff

File 8593.diff, 8.0 KB (added by Chris Beaven, 8 years ago)
  • django/utils/_os.py

    diff --git a/django/utils/_os.py b/django/utils/_os.py
    index f7b279d..2c7b88e 100644
    a b def safe_join(base, *paths): 
    3030    The final path must be located inside of the base path component (otherwise
    3131    a ValueError is raised).
    3232    """
    33     # We need to use normcase to ensure we don't false-negative on case
    34     # insensitive operating systems (like Windows).
    3533    base = force_unicode(base)
    3634    paths = [force_unicode(p) for p in paths]
    37     final_path = normcase(abspathu(join(base, *paths)))
    38     base_path = normcase(abspathu(base))
     35    final_path = abspathu(join(base, *paths))
     36    base_path = abspathu(base)
    3937    base_path_len = len(base_path)
    40     # Ensure final_path starts with base_path and that the next character after
    41     # the final path is os.sep (or nothing, in which case final_path must be
    42     # equal to base_path).
    43     if not final_path.startswith(base_path) \
     38    # Ensure final_path starts with base_path (using normcase to ensure we
     39    # don't false-negative on case insensitive operating systems like Windows)
     40    # and that the next character after the final path is os.sep (or nothing,
     41    # in which case final_path must be equal to base_path).
     42    if not normcase(final_path).startswith(normcase(base_path)) \
    4443       or final_path[base_path_len:base_path_len+1] not in ('', sep):
    4544        raise ValueError('The joined path (%s) is located outside of the base '
    4645                         'path component (%s)' % (final_path, base_path))
  • tests/regressiontests/file_storage/tests.py

    diff --git a/tests/regressiontests/file_storage/tests.py b/tests/regressiontests/file_storage/tests.py
    index e9e9d31..cdec187 100644
    a b class FileStorageTests(unittest.TestCase): 
    9090    storage_class = FileSystemStorage
    9191
    9292    def setUp(self):
    93         self.temp_dir = tempfile.mktemp()
    94         os.makedirs(self.temp_dir)
     93        self.temp_dir = tempfile.mkdtemp()
    9594        self.storage = self.storage_class(location=self.temp_dir,
    9695            base_url='/test_media_url/')
     96        # Set up a second temporary directory which is ensured to have a mixed
     97        # case name.
     98        self.temp_dir2 = tempfile.mkdtemp(suffix='aBc')
    9799
    98100    def tearDown(self):
    99101        shutil.rmtree(self.temp_dir)
     102        shutil.rmtree(self.temp_dir2)
    100103
    101104    def test_file_access_options(self):
    102105        """
    class FileStorageTests(unittest.TestCase): 
    265268        self.assertRaises(SuspiciousOperation, self.storage.exists, '..')
    266269        self.assertRaises(SuspiciousOperation, self.storage.exists, '/etc/passwd')
    267270
     271    def test_file_storage_preserves_filename_case(self):
     272        """The storage backend should preserve case of filenames."""
     273        # Create a storage backend associated with the mixed case name
     274        # directory.
     275        temp_storage = self.storage_class(location=self.temp_dir2)
     276        # Ask that storage backend to store a file with a mixed case filename.
     277        mixed_case = 'CaSe_SeNsItIvE'
     278        file = temp_storage.open(mixed_case, 'w')
     279        file.write('storage contents')
     280        file.close()
     281        self.assertEqual(os.path.join(self.temp_dir2, mixed_case),
     282                         temp_storage.path(mixed_case))
     283        temp_storage.delete(mixed_case)
     284
    268285class CustomStorage(FileSystemStorage):
    269286    def get_available_name(self, name):
    270287        """
  • tests/regressiontests/file_uploads/tests.py

    diff --git a/tests/regressiontests/file_uploads/tests.py b/tests/regressiontests/file_uploads/tests.py
    index 3c126b7..d42e027 100644
    a b class FileUploadTests(TestCase): 
    278278            # CustomUploadError is the error that should have been raised
    279279            self.assertEqual(err.__class__, uploadhandler.CustomUploadError)
    280280
     281    def test_filename_case_preservation(self):
     282        """
     283        The storage backend shouldn't mess with the case of the filenames
     284        uploaded.
     285        """
     286        # Synthesize the contents of a file upload with a mixed case filename
     287        # so we don't have to carry such a file in the Django tests source code
     288        # tree.
     289        vars = {'boundary': 'oUrBoUnDaRyStRiNg'}
     290        post_data = [
     291            '--%(boundary)s',
     292            'Content-Disposition: form-data; name="file_field"; '
     293                'filename="MiXeD_cAsE.txt"',
     294            'Content-Type: application/octet-stream',
     295            '',
     296            'file contents\n'
     297            '',
     298            '--%(boundary)s--\r\n',
     299        ]
     300        response = self.client.post(
     301            '/file_uploads/filename_case/',
     302            '\r\n'.join(post_data) % vars,
     303            'multipart/form-data; boundary=%(boundary)s' % vars
     304        )
     305        self.assertEqual(response.status_code, 200)
     306        id = int(response.content)
     307        obj = FileModel.objects.get(pk=id)
     308        # The name of the file uploaded and the file stored in the server-side
     309        # shouldn't differ.
     310        self.assertEqual(os.path.basename(obj.testfile.path), 'MiXeD_cAsE.txt')
     311
    281312class DirectoryCreationTests(unittest.TestCase):
    282313    """
    283314    Tests for error handling during directory creation
  • tests/regressiontests/file_uploads/urls.py

    diff --git a/tests/regressiontests/file_uploads/urls.py b/tests/regressiontests/file_uploads/urls.py
    index 9f814c4..a5c2702 100644
    a b urlpatterns = patterns('', 
    1111    (r'^quota/broken/$',    views.file_upload_quota_broken),
    1212    (r'^getlist_count/$',   views.file_upload_getlist_count),
    1313    (r'^upload_errors/$',   views.file_upload_errors),
     14    (r'^filename_case/$',   views.file_upload_filename_case_view),
    1415)
  • tests/regressiontests/file_uploads/views.py

    diff --git a/tests/regressiontests/file_uploads/views.py b/tests/regressiontests/file_uploads/views.py
    index dba7522..c88c775 100644
    a b def file_upload_getlist_count(request): 
    120120def file_upload_errors(request):
    121121    request.upload_handlers.insert(0, ErroringUploadHandler())
    122122    return file_upload_echo(request)
     123
     124def file_upload_filename_case_view(request):
     125    """
     126    Check adding the file to the database will preserve the filename case.
     127    """
     128    file = request.FILES['file_field']
     129    obj = FileModel()
     130    obj.testfile.save(file.name, file)
     131    return HttpResponse('%d' % obj.pk)
  • tests/regressiontests/templates/tests.py

    diff --git a/tests/regressiontests/templates/tests.py b/tests/regressiontests/templates/tests.py
    index abfdb8d..5237bb6 100644
    a b class Templates(unittest.TestCase): 
    161161        fs_loader = filesystem.Loader()
    162162        def test_template_sources(path, template_dirs, expected_sources):
    163163            if isinstance(expected_sources, list):
    164                 # Fix expected sources so they are normcased and abspathed
    165                 expected_sources = [os.path.normcase(os.path.abspath(s)) for s in expected_sources]
     164                # Fix expected sources so they are abspathed
     165                expected_sources = [os.path.abspath(s) for s in expected_sources]
    166166            # Test the two loaders (app_directores and filesystem).
    167167            func1 = lambda p, t: list(ad_loader.get_template_sources(p, t))
    168168            func2 = lambda p, t: list(fs_loader.get_template_sources(p, t))
    class Templates(unittest.TestCase): 
    205205        if os.path.normcase('/TEST') == os.path.normpath('/test'):
    206206            template_dirs = ['/dir1', '/DIR2']
    207207            test_template_sources('index.html', template_dirs,
    208                                   ['/dir1/index.html', '/dir2/index.html'])
     208                                  ['/dir1/index.html', '/DIR2/index.html'])
    209209            test_template_sources('/DIR1/index.HTML', template_dirs,
    210                                   ['/dir1/index.html'])
     210                                  ['/DIR1/index.HTML'])
    211211
    212212    def test_loader_debug_origin(self):
    213213        # Turn TEMPLATE_DEBUG on, so that the origin file name will be kept with
Back to Top