From 5a9e0c36824ffc8bb365cdb30a273d427f997bd9 Mon Sep 17 00:00:00 2001 From: Mark Haines Date: Wed, 26 Aug 2015 17:08:47 +0100 Subject: [PATCH] Handle unicode filenames given when downloading or received over federation --- synapse/rest/media/v1/base_resource.py | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/synapse/rest/media/v1/base_resource.py b/synapse/rest/media/v1/base_resource.py index 24297b20f1..ad2c9d4e74 100644 --- a/synapse/rest/media/v1/base_resource.py +++ b/synapse/rest/media/v1/base_resource.py @@ -34,6 +34,7 @@ import os import cgi import logging import urllib +import urlparse logger = logging.getLogger(__name__) @@ -43,10 +44,13 @@ def parse_media_id(request): # This allows users to append e.g. /test.png to the URL. Useful for # clients that parse the URL to see content type. server_name, media_id = request.postpath[:2] - if len(request.postpath) > 2 and is_ascii(request.postpath[-1]): - return server_name, media_id, request.postpath[-1] - else: - return server_name, media_id, None + file_name = None + if len(request.postpath) > 2: + try: + file_name = urlparse.unquote(request.postpath[-1]).decode("utf-8") + except UnicodeDecodeError: + pass + return server_name, media_id, file_name except: raise SynapseError( 404, @@ -144,6 +148,16 @@ class BaseMediaResource(Resource): upload_name = params.get("filename", None) if upload_name and not is_ascii(upload_name): upload_name = None + else: + upload_name_utf8 = params.get("filename*", None) + if upload_name_utf8.lower().startswith("utf-8''"): + upload_name = upload_name_utf8[7:] + if upload_name: + upload_name = urlparse.unquote(upload_name) + try: + upload_name = upload_name.decode("utf-8"); + except UnicodeDecodeError: + upload_name = None else: upload_name = None @@ -185,7 +199,9 @@ class BaseMediaResource(Resource): if is_ascii(upload_name): request.setHeader( b"Content-Disposition", - b"inline; filename=%s" % (upload_name.encode("utf-8"),), + b"inline; filename=%s" % ( + urllib.quote(upload_name.encode("utf-8")), + ), ) else: request.setHeader(