Fix(uri): More robust when querystring contains malformed percent sign (%).
Parse malformed percent sign as a plain "%" like [Google Search](https://www.google.com/?q=%%20%25) and other sites have done.
This commit is contained in:
@@ -178,9 +178,12 @@ if six.PY2:
|
|||||||
tokens = decoded_uri.split('%')
|
tokens = decoded_uri.split('%')
|
||||||
decoded_uri = tokens[0]
|
decoded_uri = tokens[0]
|
||||||
for token in tokens[1:]:
|
for token in tokens[1:]:
|
||||||
char, byte = _HEX_TO_BYTE[token[:2]]
|
token_partial = token[:2]
|
||||||
decoded_uri += char + token[2:]
|
if token_partial in _HEX_TO_BYTE:
|
||||||
|
char, byte = _HEX_TO_BYTE[token_partial]
|
||||||
|
else:
|
||||||
|
char, byte = '%', 0
|
||||||
|
decoded_uri += char + (token[2:] if byte else token)
|
||||||
only_ascii = only_ascii and (byte <= 127)
|
only_ascii = only_ascii and (byte <= 127)
|
||||||
|
|
||||||
# PERF(kgriffs): Only spend the time to do this if there
|
# PERF(kgriffs): Only spend the time to do this if there
|
||||||
@@ -235,7 +238,12 @@ else:
|
|||||||
tokens = decoded_uri.split(b'%')
|
tokens = decoded_uri.split(b'%')
|
||||||
decoded_uri = tokens[0]
|
decoded_uri = tokens[0]
|
||||||
for token in tokens[1:]:
|
for token in tokens[1:]:
|
||||||
decoded_uri += _HEX_TO_BYTE[token[:2]] + token[2:]
|
token_partial = token[:2]
|
||||||
|
if token_partial in _HEX_TO_BYTE:
|
||||||
|
decoded_uri += _HEX_TO_BYTE[token_partial] + token[2:]
|
||||||
|
else:
|
||||||
|
# malformed percentage like "x=%" or "y=%+"
|
||||||
|
decoded_uri += b'%' + token
|
||||||
|
|
||||||
# Convert back to str
|
# Convert back to str
|
||||||
return decoded_uri.decode('utf-8', 'replace')
|
return decoded_uri.decode('utf-8', 'replace')
|
||||||
|
|||||||
@@ -64,6 +64,16 @@ class _TestQueryParams(testing.TestBase):
|
|||||||
self.assertEqual(req.get_param_as_list('id', int), [23, 42])
|
self.assertEqual(req.get_param_as_list('id', int), [23, 42])
|
||||||
self.assertEqual(req.get_param('q'), u'\u8c46 \u74e3')
|
self.assertEqual(req.get_param('q'), u'\u8c46 \u74e3')
|
||||||
|
|
||||||
|
def test_bad_percentage(self):
|
||||||
|
query_string = 'x=%%20%+%&y=peregrine&z=%a%z%zz%1%20e'
|
||||||
|
self.simulate_request('/', query_string=query_string)
|
||||||
|
self.assertEqual(self.srmock.status, falcon.HTTP_200)
|
||||||
|
|
||||||
|
req = self.resource.req
|
||||||
|
self.assertEqual(req.get_param('x'), '% % %')
|
||||||
|
self.assertEqual(req.get_param('y'), 'peregrine')
|
||||||
|
self.assertEqual(req.get_param('z'), '%a%z%zz%1 e')
|
||||||
|
|
||||||
def test_allowed_names(self):
|
def test_allowed_names(self):
|
||||||
query_string = ('p=0&p1=23&2p=foo&some-thing=that&blank=&'
|
query_string = ('p=0&p1=23&2p=foo&some-thing=that&blank=&'
|
||||||
'some_thing=x&-bogus=foo&more.things=blah&'
|
'some_thing=x&-bogus=foo&more.things=blah&'
|
||||||
|
|||||||
Reference in New Issue
Block a user