Skip to content
Permalink
Browse files

Fix handling of non-ASCII characters in URLs. (#380)

On Python 2 everything is fine, no recoding is necessary.
Only on Python 3 the recoding has to be done.

This regression was introduced in #181.
  • Loading branch information...
icemac committed Oct 19, 2018
1 parent 391a5e4 commit 707df7360b8b77286db0caa111dab28c3b2eb5e1
Showing with 29 additions and 7 deletions.
  1. +3 −0 CHANGES.rst
  2. +4 −6 src/ZPublisher/WSGIPublisher.py
  3. +22 −1 src/ZPublisher/tests/test_WSGIPublisher.py
@@ -17,6 +17,9 @@ Bugfixes
- Fix a bug with scopes in scripts with zconsole, which made it impossible to
reach global imports in the script within a function.

- Fix handling of non-ASCII characters in URLs on Python 2 introduced on 4.0b5.
(`#380 <https://github.com/zopefoundation/Zope/pull/380>`_)


4.0b6 (2018-10-11)
------------------
@@ -241,16 +241,14 @@ def publish_module(environ, start_response,
result = ()

path_info = environ.get('PATH_INFO')
if path_info:
if path_info and PY3:
# The WSGI server automatically treats the PATH_INFO as latin-1 encoded
# bytestrings. Typically this is a false assumption as the browser
# delivers utf-8 encoded PATH_INFO. We, therefore, need to encode it
# again with latin-1 to get a utf-8 encoded bytestring. This is
# sufficient for Python 2.
# again with latin-1 to get a utf-8 encoded bytestring.
path_info = path_info.encode('latin-1')
if PY3:
# In Python 3 we need unicode here, so we decode the bytestring.
path_info = path_info.decode('utf-8')
# But in Python 3 we need text here, so we decode the bytestring.
path_info = path_info.decode('utf-8')

environ['PATH_INFO'] = path_info
with closing(BytesIO()) as stdout, closing(BytesIO()) as stderr:
@@ -1,3 +1,4 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright (c) 2009 Zope Foundation and Contributors.
@@ -10,6 +11,7 @@
# FOR A PARTICULAR PURPOSE
#
##############################################################################
import codecs
import io
import unittest

@@ -18,9 +20,12 @@
from zope.publisher.interfaces import INotFound
from zope.security.interfaces import IUnauthorized
from zope.security.interfaces import IForbidden
from six.moves.urllib_parse import quote

from ZPublisher.WSGIPublisher import get_module_info
from Testing.ZopeTestCase import FunctionalTestCase
from Testing.ZopeTestCase import ZopeTestCase
from ZPublisher.WSGIPublisher import get_module_info
import Testing.testbrowser


class WSGIResponseTests(unittest.TestCase):
@@ -543,6 +548,22 @@ def testHandleErrorsFalseBypassesExceptionResponse(self):
self._callFUT(environ, start_response, _publish)


class WSGIPublisherTests(FunctionalTestCase):

def test_can_handle_non_ascii_URLs(self):
from OFS.Image import manage_addFile
manage_addFile(self.app, 'täst', u'çöńtêñt'.encode('utf-8'))

browser = Testing.testbrowser.Browser()
browser.addHeader(
'Authorization',
'basic {}'.format(codecs.encode(
b'manager:manager_pass', 'base64').decode()))

browser.open('http://localhost/{}'.format(quote('täst')))
self.assertEqual(browser.contents.decode('utf-8'), u'çöńtêñt')


class TestLoadApp(unittest.TestCase):

def _getTarget(self):

0 comments on commit 707df73

Please sign in to comment.
You can’t perform that action at this time.