Fixed #10254: Changed the regex in get_valid_filename to allow unicode 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
This commit is contained in:
parent
ff166a3cdc
commit
668bc4f7be
|
@ -116,13 +116,13 @@ def get_valid_filename(s):
|
||||||
"""
|
"""
|
||||||
Returns the given string converted to a string that can be used for a clean
|
Returns the given string converted to a string that can be used for a clean
|
||||||
filename. Specifically, leading and trailing spaces are removed; other
|
filename. Specifically, leading and trailing spaces are removed; other
|
||||||
spaces are converted to underscores; and all non-filename-safe characters
|
spaces are converted to underscores; and anything that is not a unicode
|
||||||
are removed.
|
alphanumeric, dash, underscore, or dot, is removed.
|
||||||
>>> get_valid_filename("john's portrait in 2004.jpg")
|
>>> get_valid_filename("john's portrait in 2004.jpg")
|
||||||
u'johns_portrait_in_2004.jpg'
|
u'johns_portrait_in_2004.jpg'
|
||||||
"""
|
"""
|
||||||
s = force_unicode(s).strip().replace(' ', '_')
|
s = force_unicode(s).strip().replace(' ', '_')
|
||||||
return re.sub(r'[^-A-Za-z0-9_.]', '', s)
|
return re.sub(r'(?u)[^-\w.]', '', s)
|
||||||
get_valid_filename = allow_lazy(get_valid_filename, unicode)
|
get_valid_filename = allow_lazy(get_valid_filename, unicode)
|
||||||
|
|
||||||
def get_text_list(list_, last_word=ugettext_lazy(u'or')):
|
def get_text_list(list_, last_word=ugettext_lazy(u'or')):
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
#! -*- coding: utf-8 -*-
|
||||||
import os
|
import os
|
||||||
import errno
|
import errno
|
||||||
import shutil
|
import shutil
|
||||||
|
@ -12,6 +13,8 @@ from django.utils.hashcompat import sha_constructor
|
||||||
from models import FileModel, temp_storage, UPLOAD_TO
|
from models import FileModel, temp_storage, UPLOAD_TO
|
||||||
import uploadhandler
|
import uploadhandler
|
||||||
|
|
||||||
|
UNICODE_FILENAME = u'test-0123456789_中文_Orléans.jpg'
|
||||||
|
|
||||||
class FileUploadTests(TestCase):
|
class FileUploadTests(TestCase):
|
||||||
def test_simple_upload(self):
|
def test_simple_upload(self):
|
||||||
post_data = {
|
post_data = {
|
||||||
|
@ -32,16 +35,10 @@ class FileUploadTests(TestCase):
|
||||||
file2.write('a' * (10 * 2 ** 20))
|
file2.write('a' * (10 * 2 ** 20))
|
||||||
file2.seek(0)
|
file2.seek(0)
|
||||||
|
|
||||||
# This file contains chinese symbols for a name.
|
|
||||||
file3 = open(os.path.join(tdir, u'test_中文_Orl\u00e9ans.jpg'.encode('utf-8')), 'w+b')
|
|
||||||
file3.write('b' * (2 ** 10))
|
|
||||||
file3.seek(0)
|
|
||||||
|
|
||||||
post_data = {
|
post_data = {
|
||||||
'name': 'Ringo',
|
'name': 'Ringo',
|
||||||
'file_field1': open(file1.name),
|
'file_field1': open(file1.name),
|
||||||
'file_field2': open(file2.name),
|
'file_field2': open(file2.name),
|
||||||
'file_unicode': file3,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for key in post_data.keys():
|
for key in post_data.keys():
|
||||||
|
@ -53,8 +50,24 @@ class FileUploadTests(TestCase):
|
||||||
|
|
||||||
response = self.client.post('/file_uploads/verify/', post_data)
|
response = self.client.post('/file_uploads/verify/', post_data)
|
||||||
|
|
||||||
|
self.assertEqual(response.status_code, 200)
|
||||||
|
|
||||||
|
def test_unicode_file_name(self):
|
||||||
|
tdir = tempfile.gettempdir()
|
||||||
|
|
||||||
|
# This file contains chinese symbols and an accented char in the name.
|
||||||
|
file1 = open(os.path.join(tdir, UNICODE_FILENAME.encode('utf-8')), 'w+b')
|
||||||
|
file1.write('b' * (2 ** 10))
|
||||||
|
file1.seek(0)
|
||||||
|
|
||||||
|
post_data = {
|
||||||
|
'file_unicode': file1,
|
||||||
|
}
|
||||||
|
|
||||||
|
response = self.client.post('/file_uploads/unicode_name/', post_data)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
os.unlink(file3.name)
|
os.unlink(file1.name)
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@ import views
|
||||||
urlpatterns = patterns('',
|
urlpatterns = patterns('',
|
||||||
(r'^upload/$', views.file_upload_view),
|
(r'^upload/$', views.file_upload_view),
|
||||||
(r'^verify/$', views.file_upload_view_verify),
|
(r'^verify/$', views.file_upload_view_verify),
|
||||||
|
(r'^unicode_name/$', views.file_upload_unicode_name),
|
||||||
(r'^echo/$', views.file_upload_echo),
|
(r'^echo/$', views.file_upload_echo),
|
||||||
(r'^quota/$', views.file_upload_quota),
|
(r'^quota/$', views.file_upload_quota),
|
||||||
(r'^quota/broken/$', views.file_upload_quota_broken),
|
(r'^quota/broken/$', views.file_upload_quota_broken),
|
||||||
|
|
|
@ -5,6 +5,7 @@ from django.utils import simplejson
|
||||||
from models import FileModel
|
from models import FileModel
|
||||||
from uploadhandler import QuotaUploadHandler, ErroringUploadHandler
|
from uploadhandler import QuotaUploadHandler, ErroringUploadHandler
|
||||||
from django.utils.hashcompat import sha_constructor
|
from django.utils.hashcompat import sha_constructor
|
||||||
|
from tests import UNICODE_FILENAME
|
||||||
|
|
||||||
def file_upload_view(request):
|
def file_upload_view(request):
|
||||||
"""
|
"""
|
||||||
|
@ -29,10 +30,6 @@ def file_upload_view_verify(request):
|
||||||
form_data = request.POST.copy()
|
form_data = request.POST.copy()
|
||||||
form_data.update(request.FILES)
|
form_data.update(request.FILES)
|
||||||
|
|
||||||
# Check to see if unicode names worked out.
|
|
||||||
if not request.FILES['file_unicode'].name.endswith(u'test_\u4e2d\u6587_Orl\xe9ans.jpg'):
|
|
||||||
return HttpResponseServerError()
|
|
||||||
|
|
||||||
for key, value in form_data.items():
|
for key, value in form_data.items():
|
||||||
if key.endswith('_hash'):
|
if key.endswith('_hash'):
|
||||||
continue
|
continue
|
||||||
|
@ -53,6 +50,32 @@ def file_upload_view_verify(request):
|
||||||
|
|
||||||
return HttpResponse('')
|
return HttpResponse('')
|
||||||
|
|
||||||
|
def file_upload_unicode_name(request):
|
||||||
|
|
||||||
|
# Check to see if unicode name came through properly.
|
||||||
|
if not request.FILES['file_unicode'].name.endswith(UNICODE_FILENAME):
|
||||||
|
return HttpResponseServerError()
|
||||||
|
|
||||||
|
response = None
|
||||||
|
|
||||||
|
# Check to make sure the exotic characters are preserved even
|
||||||
|
# through file save.
|
||||||
|
uni_named_file = request.FILES['file_unicode']
|
||||||
|
obj = FileModel.objects.create(testfile=uni_named_file)
|
||||||
|
if not obj.testfile.name.endswith(uni_named_file.name):
|
||||||
|
response = HttpResponseServerError()
|
||||||
|
|
||||||
|
# Cleanup the object with its exotic file name immediately.
|
||||||
|
# (shutil.rmtree used elsewhere in the tests to clean up the
|
||||||
|
# upload directory has been seen to choke on unicode
|
||||||
|
# filenames on Windows.)
|
||||||
|
obj.delete()
|
||||||
|
|
||||||
|
if response:
|
||||||
|
return response
|
||||||
|
else:
|
||||||
|
return HttpResponse('')
|
||||||
|
|
||||||
def file_upload_echo(request):
|
def file_upload_echo(request):
|
||||||
"""
|
"""
|
||||||
Simple view to echo back info about uploaded files for tests.
|
Simple view to echo back info about uploaded files for tests.
|
||||||
|
|
Loading…
Reference in New Issue