Skip to content

Commit

Permalink
1.7.1dev: merge [17820] from 1.6-stable (fix for #13758)
Browse files Browse the repository at this point in the history
git-svn-id: http://trac.edgewall.org/intertrac/log:/trunk@17821 af82e41b-90c4-0310-8c96-b1721e28e2e2
  • Loading branch information
jomae committed Jun 9, 2024
2 parents f28a8c1 + 7c944f6 commit 83c7b0a
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 7 deletions.
2 changes: 1 addition & 1 deletion trac/web/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -524,7 +524,7 @@ def parse_form_data(environ):
data = environ['wsgi.input'].read(length)
pairs = urllib.parse.parse_qsl(
str(data, 'utf-8'), keep_blank_values=True,
strict_parsing=True, encoding='utf-8', errors='strict')
strict_parsing=False, encoding='utf-8', errors='strict')
for name, value in pairs:
_raise_if_null_bytes(name)
_raise_if_null_bytes(value)
Expand Down
40 changes: 34 additions & 6 deletions trac/web/tests/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,10 +72,26 @@ def _make_environ(scheme='http', server_name='example.org',
environ.update(kwargs)
for key, value in environ.items():
if isinstance(value, bytes):
environ[key] = str(value, 'utf-8')
environ[key] = str(value, 'iso-8859-1') # WSGI "bytes-as-unicode"
return environ


def _make_environ_qs(method='GET', query_string=b'', **kwargs):
if isinstance(query_string, str):
query_string = query_string.encode('utf-8')
if method == 'GET':
kw = {'QUERY_STRING': str(query_string, 'iso-8859-1')} \
if query_string else {}
elif method == 'POST':
kw = {'wsgi.input': io.BytesIO(query_string),
'CONTENT_LENGTH': str(len(query_string)),
'CONTENT_TYPE': 'application/x-www-form-urlencoded'}
else:
raise AssertionError('Wrong method {!r}'.format(method))
kw.update(kwargs)
return _make_environ(method=method, **kw)


def _make_req(environ, authname='admin', chrome=None, form_token='A' * 40,
locale=None, perm=MockPerm(), tz=utc, use_xsendfile=False,
xsendfile_header='X-Sendfile'):
Expand Down Expand Up @@ -470,7 +486,8 @@ def test_read_size(self):
req = Request(environ, None)
self.assertEqual(b'test', req.read(size=4))

def _test_qs_with_null_bytes(self, environ):
def _test_qs_with_null_bytes(self, method, qs):
environ = _make_environ_qs(method=method, query_string=qs)
req = Request(environ, None)
try:
req.args['action']
Expand All @@ -481,12 +498,23 @@ def _test_qs_with_null_bytes(self, environ):
self.fail("HTTPBadRequest not raised.")

def test_qs_with_null_bytes_for_name(self):
environ = _make_environ(method='GET', QUERY_STRING='acti\x00n=fOO')
self._test_qs_with_null_bytes(environ)
qs = b'acti\x00n=fOO'
self._test_qs_with_null_bytes('GET', qs)
self._test_qs_with_null_bytes('POST', qs)

def test_qs_with_null_bytes_for_value(self):
environ = _make_environ(method='GET', QUERY_STRING='action=f\x00O')
self._test_qs_with_null_bytes(environ)
qs = b'action=f\x00O'
self._test_qs_with_null_bytes('GET', qs)
self._test_qs_with_null_bytes('POST', qs)

def test_non_strict_qs(self):
qs = b'type=defect&owner=&or&type=&owner=john&=unnamed'
expected = [('type', 'defect'), ('owner', ''), ('or', ''),
('type', ''), ('owner', 'john'), ('', 'unnamed')]
req = Request(_make_environ_qs('GET', qs), None)
self.assertEqual(expected, req.arg_list)
req = Request(_make_environ_qs('POST', qs), None)
self.assertEqual(expected, req.arg_list)

def test_post_with_unnamed_value(self):
boundary = '_BOUNDARY_'
Expand Down

0 comments on commit 83c7b0a

Please sign in to comment.