Merge ~cjwatson/launchpad:py3-fix-request-input-decoding into launchpad:master

Proposed by Colin Watson
Status: Merged
Approved by: Colin Watson
Approved revision: 544b80137d3be356e298dbbfdc81dd54fe9ec6b4
Merge reported by: Otto Co-Pilot
Merged at revision: not available
Proposed branch: ~cjwatson/launchpad:py3-fix-request-input-decoding
Merge into: launchpad:master
Diff against target: 75 lines (+21/-10)
3 files modified
lib/lp/services/webapp/servers.py (+10/-9)
lib/lp/services/webapp/tests/test_servers.py (+10/-1)
requirements/launchpad.txt (+1/-0)
Reviewer Review Type Date Requested Status
Cristian Gonzalez (community) Approve
Review via email: mp+406315@code.launchpad.net

Commit message

Fix handling of request inputs on Python 3

Description of the change

Cherry-pick https://github.com/zopefoundation/zope.publisher/pull/66 to get better handling of non-ISO-8859-1 URL-encoded form input on Python 3. The exact nature of our countermeasures for zope.publisher's oddities has to change around a bit (and `get_query_string_params` no longer calls `BrowserRequest._decode`, which is probably a good thing on the whole), but most of the complexity will now simplify away once we're on Python 3 everywhere.

Dependencies MP: https://code.launchpad.net/~cjwatson/lp-source-dependencies/+git/lp-source-dependencies/+merge/406314

To post a comment you must log in.
Revision history for this message
Cristian Gonzalez (cristiangsp) wrote :

Looks good!

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/lib/lp/services/webapp/servers.py b/lib/lp/services/webapp/servers.py
2index 5693f92..69a443c 100644
3--- a/lib/lp/services/webapp/servers.py
4+++ b/lib/lp/services/webapp/servers.py
5@@ -529,19 +529,20 @@ def get_query_string_params(request):
6 if query_string is None:
7 query_string = ''
8
9- # PEP-3333 specifies that strings must only contain codepoints
10- # representable in ISO-8859-1.
11 kwargs = {}
12 if not six.PY2:
13- kwargs['encoding'] = 'ISO-8859-1'
14+ kwargs['encoding'] = 'UTF-8'
15 kwargs['errors'] = 'replace'
16 parsed_qs = parse_qs(query_string, keep_blank_values=True, **kwargs)
17- # Use BrowserRequest._decode() for decoding the received parameters.
18- decoded_qs = {}
19- for key, values in six.iteritems(parsed_qs):
20- decoded_qs[key] = [
21- request._decode(value) for value in values]
22- return decoded_qs
23+ if six.PY2:
24+ decoded_qs = {}
25+ for key, values in six.iteritems(parsed_qs):
26+ decoded_qs[key] = [
27+ (value.decode('UTF-8', 'replace') if isinstance(value, bytes)
28+ else value)
29+ for value in values]
30+ parsed_qs = decoded_qs
31+ return parsed_qs
32
33
34 class LaunchpadBrowserRequestMixin:
35diff --git a/lib/lp/services/webapp/tests/test_servers.py b/lib/lp/services/webapp/tests/test_servers.py
36index ab0f26a..ed66bfa 100644
37--- a/lib/lp/services/webapp/tests/test_servers.py
38+++ b/lib/lp/services/webapp/tests/test_servers.py
39@@ -21,6 +21,7 @@ from lazr.restful.testing.webservice import (
40 IGenericEntry,
41 WebServiceTestCase,
42 )
43+import six
44 from talisker.context import Context
45 from talisker.logs import logging_context
46 from zope.component import (
47@@ -440,7 +441,15 @@ class TestBasicLaunchpadRequest(TestCase):
48 def test_request_with_invalid_query_string_recovers(self):
49 # When the query string has invalid utf-8, it is decoded with
50 # replacement.
51- env = {'QUERY_STRING': 'field.title=subproc\xe9s '}
52+ if six.PY2:
53+ env = {'QUERY_STRING': 'field.title=subproc\xe9s '}
54+ else:
55+ # PEP 3333 requires environment variables to be native strings,
56+ # so we can't actually get a bytes object in here on Python 3
57+ # (both because the WSGI runner will never put it there, and
58+ # because parse_qs would crash if we did). Test the next best
59+ # thing, namely percent-encoded invalid UTF-8.
60+ env = {'QUERY_STRING': 'field.title=subproc%E9s '}
61 request = LaunchpadBrowserRequest(io.BytesIO(b''), env)
62 self.assertEqual(
63 [u'subproc\ufffds '], request.query_string_params['field.title'])
64diff --git a/requirements/launchpad.txt b/requirements/launchpad.txt
65index 7eee4bf..e9a8867 100644
66--- a/requirements/launchpad.txt
67+++ b/requirements/launchpad.txt
68@@ -175,6 +175,7 @@ zope.app.http==4.0.1
69 zope.app.publication==4.3.1
70 zope.app.publisher==4.2.0
71 zope.app.wsgi==4.3.0
72+zope.publisher==6.0.2+lp1
73 # lp:~launchpad-committers/zope.session:launchpad
74 zope.session==4.3.0+lp1
75 zope.testbrowser==5.5.1

Subscribers

People subscribed via source and target branches

to status/vote changes: