Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Fixed #10254: Changed the regex in get_valid_filename to allow unicod…

…e alphanumerics (thanks gulliver). Also updated the file_uploads test for this case to check the name after saving the uploaded file. As it was the test ensured that files with unicode characters in their names could be uploaded, but it wasn't actually ensuring that the unicode characters were preserved through save.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@10388 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
commit 668bc4f7bef79c7177bfa5b7dabd1403e0d6fa30 1 parent ff166a3
Karen Tracey authored April 04, 2009
6  django/utils/text.py
@@ -116,13 +116,13 @@ def get_valid_filename(s):
116 116
     """
117 117
     Returns the given string converted to a string that can be used for a clean
118 118
     filename. Specifically, leading and trailing spaces are removed; other
119  
-    spaces are converted to underscores; and all non-filename-safe characters
120  
-    are removed.
  119
+    spaces are converted to underscores; and anything that is not a unicode
  120
+    alphanumeric, dash, underscore, or dot, is removed.
121 121
     >>> get_valid_filename("john's portrait in 2004.jpg")
122 122
     u'johns_portrait_in_2004.jpg'
123 123
     """
124 124
     s = force_unicode(s).strip().replace(' ', '_')
125  
-    return re.sub(r'[^-A-Za-z0-9_.]', '', s)
  125
+    return re.sub(r'(?u)[^-\w.]', '', s)
126 126
 get_valid_filename = allow_lazy(get_valid_filename, unicode)
127 127
 
128 128
 def get_text_list(list_, last_word=ugettext_lazy(u'or')):
27  tests/regressiontests/file_uploads/tests.py
... ...
@@ -1,3 +1,4 @@
  1
+#! -*- coding: utf-8 -*-
1 2
 import os
2 3
 import errno
3 4
 import shutil
@@ -12,6 +13,8 @@
12 13
 from models import FileModel, temp_storage, UPLOAD_TO
13 14
 import uploadhandler
14 15
 
  16
+UNICODE_FILENAME = u'test-0123456789_中文_Orléans.jpg'
  17
+
15 18
 class FileUploadTests(TestCase):
16 19
     def test_simple_upload(self):
17 20
         post_data = {
@@ -32,16 +35,10 @@ def test_large_upload(self):
32 35
         file2.write('a' * (10 * 2 ** 20))
33 36
         file2.seek(0)
34 37
 
35  
-        # This file contains chinese symbols for a name.
36  
-        file3 = open(os.path.join(tdir, u'test_中文_Orl\u00e9ans.jpg'.encode('utf-8')), 'w+b')
37  
-        file3.write('b' * (2 ** 10))
38  
-        file3.seek(0)
39  
-
40 38
         post_data = {
41 39
             'name': 'Ringo',
42 40
             'file_field1': open(file1.name),
43 41
             'file_field2': open(file2.name),
44  
-            'file_unicode': file3,
45 42
             }
46 43
 
47 44
         for key in post_data.keys():
@@ -53,8 +50,24 @@ def test_large_upload(self):
53 50
 
54 51
         response = self.client.post('/file_uploads/verify/', post_data)
55 52
 
  53
+        self.assertEqual(response.status_code, 200)
  54
+
  55
+    def test_unicode_file_name(self):
  56
+        tdir = tempfile.gettempdir()
  57
+
  58
+        # This file contains chinese symbols and an accented char in the name.
  59
+        file1 = open(os.path.join(tdir, UNICODE_FILENAME.encode('utf-8')), 'w+b')
  60
+        file1.write('b' * (2 ** 10))
  61
+        file1.seek(0)
  62
+
  63
+        post_data = {
  64
+            'file_unicode': file1,
  65
+            }
  66
+
  67
+        response = self.client.post('/file_uploads/unicode_name/', post_data)
  68
+
56 69
         try:
57  
-            os.unlink(file3.name)
  70
+            os.unlink(file1.name)
58 71
         except:
59 72
             pass
60 73
 
1  tests/regressiontests/file_uploads/urls.py
@@ -4,6 +4,7 @@
4 4
 urlpatterns = patterns('',
5 5
     (r'^upload/$',          views.file_upload_view),
6 6
     (r'^verify/$',          views.file_upload_view_verify),
  7
+    (r'^unicode_name/$',    views.file_upload_unicode_name),
7 8
     (r'^echo/$',            views.file_upload_echo),
8 9
     (r'^quota/$',           views.file_upload_quota),
9 10
     (r'^quota/broken/$',    views.file_upload_quota_broken),
31  tests/regressiontests/file_uploads/views.py
@@ -5,6 +5,7 @@
5 5
 from models import FileModel
6 6
 from uploadhandler import QuotaUploadHandler, ErroringUploadHandler
7 7
 from django.utils.hashcompat import sha_constructor
  8
+from tests import UNICODE_FILENAME
8 9
 
9 10
 def file_upload_view(request):
10 11
     """
@@ -29,10 +30,6 @@ def file_upload_view_verify(request):
29 30
     form_data = request.POST.copy()
30 31
     form_data.update(request.FILES)
31 32
 
32  
-    # Check to see if unicode names worked out.
33  
-    if not request.FILES['file_unicode'].name.endswith(u'test_\u4e2d\u6587_Orl\xe9ans.jpg'):
34  
-        return HttpResponseServerError()
35  
-
36 33
     for key, value in form_data.items():
37 34
         if key.endswith('_hash'):
38 35
             continue
@@ -53,6 +50,32 @@ def file_upload_view_verify(request):
53 50
 
54 51
     return HttpResponse('')
55 52
 
  53
+def file_upload_unicode_name(request):
  54
+
  55
+    # Check to see if unicode name came through properly.
  56
+    if not request.FILES['file_unicode'].name.endswith(UNICODE_FILENAME):
  57
+        return HttpResponseServerError()
  58
+
  59
+    response = None
  60
+
  61
+    # Check to make sure the exotic characters are preserved even
  62
+    # through file save.
  63
+    uni_named_file = request.FILES['file_unicode']
  64
+    obj = FileModel.objects.create(testfile=uni_named_file)
  65
+    if not obj.testfile.name.endswith(uni_named_file.name):
  66
+        response = HttpResponseServerError()
  67
+
  68
+    # Cleanup the object with its exotic file name immediately.
  69
+    # (shutil.rmtree used elsewhere in the tests to clean up the
  70
+    # upload directory has been seen to choke on unicode
  71
+    # filenames on Windows.)
  72
+    obj.delete()
  73
+
  74
+    if response:
  75
+        return response
  76
+    else:
  77
+        return HttpResponse('')
  78
+
56 79
 def file_upload_echo(request):
57 80
     """
58 81
     Simple view to echo back info about uploaded files for tests.

0 notes on commit 668bc4f

Please sign in to comment.
Something went wrong with that request. Please try again.