py38: cgi lost some names

Drive-by: always use quote=True; it basically never hurts.

Change-Id: Id91fdd19f226e9ec0d9c702d40d041c385c52b88
This commit is contained in:
Tim Burke 2019-10-14 18:35:00 -07:00
parent 8efaa3556f
commit e3ee6ce31a
4 changed files with 29 additions and 21 deletions

View File

@ -123,13 +123,13 @@ Example usage of this middleware via ``swift``:
"""
import cgi
import json
import six
import time
from six.moves.urllib.parse import urlparse
from swift.common.request_helpers import html_escape
from swift.common.utils import human_readable, split_path, config_true_value, \
quote, register_swift_info, get_logger
from swift.common.wsgi import make_env, WSGIContext
@ -243,7 +243,7 @@ class _StaticWebContext(WSGIContext):
'Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">\n' \
'<html>\n' \
'<head>\n' \
'<title>Listing of %s</title>\n' % cgi.escape(label)
'<title>Listing of %s</title>\n' % html_escape(label)
if self._listings_css:
body += ' <link rel="stylesheet" type="text/css" ' \
'href="%s" />\n' % self._build_css_path(prefix or '')
@ -290,7 +290,7 @@ class _StaticWebContext(WSGIContext):
'<html>\n' \
' <head>\n' \
' <title>Listing of %s</title>\n' % \
cgi.escape(label)
html_escape(label)
if self._listings_css:
body += ' <link rel="stylesheet" type="text/css" ' \
'href="%s" />\n' % (self._build_css_path(prefix))
@ -309,7 +309,7 @@ class _StaticWebContext(WSGIContext):
' <th class="colname">Name</th>\n' \
' <th class="colsize">Size</th>\n' \
' <th class="coldate">Date</th>\n' \
' </tr>\n' % cgi.escape(label)
' </tr>\n' % html_escape(label)
if prefix:
body += ' <tr id="parent" class="item">\n' \
' <td class="colname"><a href="../">../</a></td>\n' \
@ -327,7 +327,7 @@ class _StaticWebContext(WSGIContext):
' <td class="colsize">&nbsp;</td>\n' \
' <td class="coldate">&nbsp;</td>\n' \
' </tr>\n' % \
(quote(subdir), cgi.escape(subdir))
(quote(subdir), html_escape(subdir))
for item in listing:
if 'name' in item:
name = item['name'] if six.PY3 else \
@ -338,17 +338,17 @@ class _StaticWebContext(WSGIContext):
item['content_type'].encode('utf-8')
bytes = human_readable(item['bytes'])
last_modified = (
cgi.escape(item['last_modified'] if six.PY3 else
item['last_modified'].encode('utf-8')).
html_escape(item['last_modified'] if six.PY3 else
item['last_modified'].encode('utf-8')).
split('.')[0].replace('T', ' '))
body += ' <tr class="item %s">\n' \
' <td class="colname"><a href="%s">%s</a></td>\n' \
' <td class="colsize">%s</td>\n' \
' <td class="coldate">%s</td>\n' \
' </tr>\n' % \
(' '.join('type-' + cgi.escape(t.lower(), quote=True)
(' '.join('type-' + html_escape(t.lower())
for t in content_type.split('/')),
quote(name), cgi.escape(name),
quote(name), html_escape(name),
bytes, last_modified)
body += ' </table>\n' \
' </body>\n' \

View File

@ -13,7 +13,6 @@
# See the License for the specific language governing permissions and
# limitations under the License.
import cgi
import os
import random
import re
@ -28,6 +27,7 @@ from swift.common.middleware.x_profile.exceptions import MethodNotAllowed
from swift.common.middleware.x_profile.exceptions import DataLoadFailure
from swift.common.middleware.x_profile.exceptions import ProfileException
from swift.common.middleware.x_profile.profile_model import Stats2
from swift.common.request_helpers import html_escape
PLOTLIB_INSTALLED = True
try:
@ -454,7 +454,7 @@ class HTMLViewer(object):
fmt = '<span id="L%d" rel="#L%d">%' + max_width\
+ 'd|<code>%s</code></span>'
for line in lines:
l = cgi.escape(line, quote=None)
l = html_escape(line)
i = i + 1
if i == lineno:
fmt2 = '<span id="L%d" style="background-color: \
@ -518,7 +518,7 @@ class HTMLViewer(object):
html.append('<td>-</td>')
else:
html.append('<td>%f</td>' % (float(ct) / cc))
nfls = cgi.escape(stats.func_std_string(func))
nfls = html_escape(stats.func_std_string(func))
if nfls.split(':')[0] not in ['', 'profile'] and\
os.path.isfile(nfls.split(':')[0]):
html.append('<td><a href="%s/%s%s?format=python#L%d">\
@ -532,5 +532,5 @@ class HTMLViewer(object):
--></a></td></tr>' % (app_path,
profile_id, nfls))
except Exception as ex:
html.append("Exception:" % str(ex))
html.append("Exception:" + str(ex))
return ''.join(html)

View File

@ -48,6 +48,15 @@ OBJECT_SYSMETA_CONTAINER_UPDATE_OVERRIDE_PREFIX = \
'x-object-sysmeta-container-update-override-'
if six.PY2:
import cgi
def html_escape(s, quote=True):
return cgi.escape(s, quote=quote)
else:
from html import escape as html_escape # noqa: F401
def get_param(req, name, default=None):
"""
Get parameters from an HTTP request ensuring proper handling UTF-8

View File

@ -14,11 +14,10 @@
# limitations under the License.
import unittest
import cgi
import mock
import six
from six.moves.urllib.parse import quote
from six.moves.urllib.parse import quote, parse_qsl
from swift.common import swob
from swift.common.swob import Request
@ -357,7 +356,7 @@ class TestS3ApiBucket(S3ApiTestCase):
self.assertEqual(elem.find('./MaxKeys').text, '5')
_, path = self.swift.calls[-1]
_, query_string = path.split('?')
args = dict(cgi.parse_qsl(query_string))
args = dict(parse_qsl(query_string))
self.assertEqual(args['limit'], '6')
req = Request.blank('/%s?max-keys=5000' % bucket_name,
@ -369,7 +368,7 @@ class TestS3ApiBucket(S3ApiTestCase):
self.assertEqual(elem.find('./MaxKeys').text, '5000')
_, path = self.swift.calls[-1]
_, query_string = path.split('?')
args = dict(cgi.parse_qsl(query_string))
args = dict(parse_qsl(query_string))
self.assertEqual(args['limit'], '1001')
def test_bucket_GET_str_max_keys(self):
@ -416,7 +415,7 @@ class TestS3ApiBucket(S3ApiTestCase):
self.assertEqual(elem.find('./Delimiter').text, 'a')
_, path = self.swift.calls[-1]
_, query_string = path.split('?')
args = dict(cgi.parse_qsl(query_string))
args = dict(parse_qsl(query_string))
self.assertEqual(args['delimiter'], 'a')
self.assertEqual(args['marker'], 'b')
self.assertEqual(args['prefix'], 'c')
@ -435,7 +434,7 @@ class TestS3ApiBucket(S3ApiTestCase):
self.assertEqual(elem.find('./Delimiter').text, 'a')
_, path = self.swift.calls[-1]
_, query_string = path.split('?')
args = dict(cgi.parse_qsl(query_string))
args = dict(parse_qsl(query_string))
self.assertEqual(args['delimiter'], 'a')
# "start-after" is converted to "marker"
self.assertEqual(args['marker'], 'b')
@ -456,7 +455,7 @@ class TestS3ApiBucket(S3ApiTestCase):
self.assertEqual(elem.find('./Delimiter').text, '\xef\xbc\xa1')
_, path = self.swift.calls[-1]
_, query_string = path.split('?')
args = dict(cgi.parse_qsl(query_string))
args = dict(parse_qsl(query_string))
self.assertEqual(args['delimiter'], '\xef\xbc\xa1')
self.assertEqual(args['marker'], '\xef\xbc\xa2')
self.assertEqual(args['prefix'], '\xef\xbc\xa3')
@ -476,7 +475,7 @@ class TestS3ApiBucket(S3ApiTestCase):
self.assertEqual(elem.find('./Delimiter').text, '\xef\xbc\xa1')
_, path = self.swift.calls[-1]
_, query_string = path.split('?')
args = dict(cgi.parse_qsl(query_string))
args = dict(parse_qsl(query_string))
self.assertEqual(args['delimiter'], '\xef\xbc\xa1')
self.assertEqual(args['marker'], '\xef\xbc\xa2')
self.assertEqual(args['prefix'], '\xef\xbc\xa3')