diff --git a/trac/attachment.py b/trac/attachment.py index ffcc7a0..3b9e048 100644 --- a/trac/attachment.py +++ b/trac/attachment.py @@ -43,7 +43,7 @@ from trac.util.compat import sha1 from trac.util.datefmt import format_datetime, from_utimestamp, \ to_datetime, to_utimestamp, utc from trac.util.text import exception_to_unicode, path_to_unicode, \ - pretty_size, print_table, unicode_unquote + pretty_size, print_table, stripws, unicode_unquote from trac.util.translation import _, tag_ from trac.web import HTTPBadRequest, IRequestHandler, RequestDone from trac.web.chrome import (INavigationContributor, add_ctxtnav, add_link, @@ -680,6 +680,12 @@ class AttachmentModule(Component): # Internal methods + _control_codes_re = re.compile( + '[' + + ''.join(filter(lambda c: unicodedata.category(c) == 'Cc', + map(unichr, xrange(0x10000)))) + + ']') + def _do_save(self, req, attachment): req.perm(attachment.resource).require('ATTACHMENT_CREATE') parent_resource = attachment.resource.parent @@ -713,12 +719,14 @@ class AttachmentModule(Component): # Files uploaded from OS X might be in NFD. filename = unicodedata.normalize('NFC', unicode(upload.filename, 'utf-8')) - filename = filename.strip() + # Replace control codes with spaces, e.g. NUL, LF, DEL, U+009F + filename = self._control_codes_re.sub(' ', filename) # Replace backslashes with slashes if filename is Windows full path if filename.startswith('\\') or re.match(r'[A-Za-z]:\\', filename): filename = filename.replace('\\', '/') # We want basename to be delimited by only slashes on all platforms filename = posixpath.basename(filename) + filename = stripws(filename) if not filename: raise TracError(_('No file uploaded')) # Now the filename is known, update the attachment resource