Commit b3039664 authored by Kazuhiko Shiozaki's avatar Kazuhiko Shiozaki

cgi.escape is deprecated in Python 3.2 and removed in Python 3.8.

parent ce63a24d
import cgi
from Products.PythonScripts.standard import html_quote
def escapeInnerHTML(string_to_escape):
return cgi.escape("%s" % string_to_escape, quote=False)
def escapeAttributeProperty(string_to_escape):
return cgi.escape("%s" % string_to_escape, quote=True)
def escape(string_to_escape):
return html_quote("%s" % string_to_escape)
web_site_value = context.getWebSiteValue()
......@@ -15,7 +12,7 @@ if (web_site_value is not None):
for category_relative_url in category_relative_url_list:
base_category, _ = category_relative_url.split('/', 1)
result[category_relative_url.replace('/', '__')] = '<ul>%s</ul>' % ''.join(['<li><a href="%s">%s</a></li>' % (escapeAttributeProperty(x.getReference()), escapeInnerHTML(x.getTitle())) for x in web_site_value.getDocumentValueList(
result[category_relative_url.replace('/', '__')] = '<ul>%s</ul>' % ''.join(['<li><a href="%s">%s</a></li>' % (escape(x.getReference()), escape(x.getTitle())) for x in web_site_value.getDocumentValueList(
sort_on=[['title', 'ASC']],
**{'%s__relative_url' % base_category: category_relative_url}
)])
......
from cgi import escape
from Products.PythonScripts.standard import html_quote
portal = context.getPortalObject()
skin_folder = portal.portal_skins[original_skin_name]
new_skin_folder = portal.portal_skins[new_skin_name]
......@@ -38,7 +38,7 @@ for original_form in skin_folder.objectValues():
original_field.absolute_url(), new_field.absolute_url()))
output_list += ("<tr><td>%s</td></tr>" % "</td><td>".join(
map(escape, ('[%s]' % key if T else key, str(old), str(new[key]))))
map(html_quote, ('[%s]' % key if T else key, str(old), str(new[key]))))
for T, old, new in ((0, original_value_dict, new_value_dict),
(1, original_value_tales, new_value_tales))
for key, old in old.iteritems()
......
import cgi
from Products.PythonScripts.standard import html_quote
import re
web_section = context
web_site = web_section.getWebSiteValue()
def _(string_to_escape):
return cgi.escape("%s" % string_to_escape, quote=False)
def __(string_to_escape):
return cgi.escape("%s" % string_to_escape, quote=True)
return html_quote("%s" % string_to_escape)
  • @kazuhiko I think you broke the previous behaviour, as escaping an URL is different from escaping HTML.

    Using the html lib allows to keep same behaviour.

    def _(string_to_escape):
      return html.escape("%s" % string_to_escape, quote=False)
    
    def __(string_to_escape):
      return html.escape("%s" % string_to_escape, quote=True)

    If html can not be used directly, maybe you'll have to use url_quote, but as I don't know if it has the same behaviour, it makes me a bit nervous.

    In any case, this change must be removed ASAP.

    /cc @jerome

  • Let's imagine string_to_escape is '<">'.

    Before : <tag attr="&lt;quot;&gt;">&lt;"&gt;</tag>

    After : <tag attr="&lt;quot;&gt;">&lt;&quot;&gt;</tag>

    For HTML, both are same in reality (not for XML though), thus I did this change.

    @kazuhiko I think you broke the previous behaviour, as escaping an URL is different from escaping HTML.

    Like the example above, for URL, well for attribute value, the behaviour is same as before.

  • Yes, in our understanding, it was "always better" to use quote=True. Do we have an example where this is not the case ?

    We also discussed that using a page template would be easier for this kind of code building html (except for the recursion), if there are cases where always using quote=True is not good, I'm also wondering if there would be problems with using page templates instead.

  • if html_quote uses quote=True, no regression has been introduced, except making the HTML a bit less readable for a human.

    We also discussed that using a page template would be easier for this kind of code building html (except for the recursion), if there are cases where always using quote=True is not good, I'm also wondering if there would be problems with using page templates instead.

    @Nicolas already asked me this. I tried, but gave up (because I really don't know how to do, and I prefer not to add too much complexity here)

  • Thanks, so the conclusion so far is that we can keep this change if I understood.

  • yes. I was afraid too fast...

Please register or sign in to reply
def generateSectionListHTML(result_list, section_list):
......@@ -18,7 +14,7 @@ def generateSectionListHTML(result_list, section_list):
for section in section_list:
# Add missing / suffix to get correct relative url generation
# XXX Fix WebSection_getSiteMapTree instead, but no idea what would be the site effects
result_list.append('<li><a href="%s">%s</a>' % (__(section['url'] + '/'), _(section['translated_title'])))
result_list.append('<li><a href="%s">%s</a>' % (_(section['url'] + '/'), _(section['translated_title'])))
generateSectionListHTML(result_list, section['subsection'])
result_list.append('</li>')
result_list.append('</ul>')
......@@ -41,8 +37,8 @@ def generateDocumentListHTML(result_list, document_list):
_(section['translated_title']),
('<p class="p-summary">%s</p>' % _(section['description'])) if section.get('description') else '',
('<p class="p-author h-card">%s</p>' % _(section['document'].Document_getContributorTitleList()[0])),
__(section['url']),
__(publication_date.HTML4()),
_(section['url']),
_(publication_date.HTML4()),
_(publication_date.rfc822())
))
result_list.append('</ul></aside>')
......@@ -65,12 +61,12 @@ for language in available_language_set:
website_url_set[language] = re.sub(website_url_pattern, r'%s/%s/\1' % (root_website_url, language), web_site.absolute_url())
for language, url in website_url_set.items():
result_list += '<li><a href="%s" hreflang="%s"><abbr lang="%s">%s</abbr></a></li>' % (__(url), __(language), __(language), _(language))
result_list += '<li><a href="%s" hreflang="%s"><abbr lang="%s">%s</abbr></a></li>' % (_(url), _(language), _(language), _(language))
result_list.append('</ul></nav>')
# Sitemap
result_list.append('<nav id="sitemap">')
result_list.append('<a href="%s">%s</a>' % (__(web_site.absolute_url()), _(web_site.getTranslatedTitle())))
result_list.append('<a href="%s">%s</a>' % (_(web_site.absolute_url()), _(web_site.getTranslatedTitle())))
generateSectionListHTML(result_list, web_site.WebSection_getSiteMapTree(include_document=False, depth=99))
result_list.append('</nav>')
......
import re
import cgi
from Products.PythonScripts.standard import html_quote
from Acquisition import aq_base
from AccessControl import Unauthorized
from Products.CMFCore.utils import _checkPermission
......@@ -73,8 +73,8 @@ def grep(self, pattern, A=0, B=0, r=1, i=0, highlight=1, first_occurence=0):
html_element_list = [doctype, html, head, '<body>' '<p>']
result_list = []
for url, path, line in result:
path = cgi.escape(path)
line = cgi.escape(line)
path = html_quote(path)
line = html_quote(line)
if highlight:
line = rx.sub('<span class="highlight">\g<0></span>', line)
if ExternalEditor is None:
......
......@@ -220,8 +220,8 @@ def generateInformation(dir, info=id, err=None):
if str is not bytes:
k = k.encode()
for v in (v,) if type(v) is bytes else v:
xml.write(b' <%s>%s</%s>\n' % (k, escape(v) if str is bytes else
escape(v.decode()).encode(), k))
xml.write(b' <%s>%s</%s>\n' % (k, escape(v, quote=False) if str is bytes else
escape(v.decode(), quote=False).encode(), k))
xml.write(b' </template>\n')
info('done\n')
xml.write(b'</repository>\n')
......
......@@ -40,7 +40,7 @@ from AccessControl.SecurityManagement import setSecurityManager
from Products.ERP5Type.Utils import _setSuperSecurityManager
from App.config import getConfiguration
from Products.ERP5Type.Cache import CachingMethod
from cgi import escape
from Products.PythonScripts.standard import html_quote
import logging
......@@ -257,14 +257,14 @@ class IntrospectionTool(LogMixin, BaseTool):
"""
Tail the Event Log.
"""
return escape(self._tailFile(self.__getEventLogPath(), 500))
return html_quote(self._tailFile(self.__getEventLogPath(), 500))
security.declareProtected(Permissions.ManagePortal, 'tailAccessLog')
def tailAccessLog(self):
"""
Tail the Event Log.
"""
return escape(self._tailFile(self.__getAccessLogPath(), 50))
return html_quote(self._tailFile(self.__getAccessLogPath(), 50))
security.declareProtected(Permissions.ManagePortal, 'getAccessLog')
def getAccessLog(self, compressed=1, REQUEST=None):
......
......@@ -53,9 +53,9 @@ from ZTUtils import make_query
from Products.ERP5Type.Globals import InitializeClass, get_request
from Products.PythonScripts.Utility import allow_class
from Products.PythonScripts.standard import html_quote
from Products.PageTemplates.PageTemplateFile import PageTemplateFile
from warnings import warn
import cgi
import six
DEFAULT_LISTBOX_DISPLAY_STYLE = 'table'
......@@ -2475,7 +2475,7 @@ class ListBoxHTMLRendererLine(ListBoxRendererLine):
# If error on current field, we should display message
if key in error_dict:
error_text = error_dict[key].error_text
error_text = cgi.escape(error_text)
error_text = html_quote(error_text)
if isinstance(error_text, str):
error_mapping = getattr(error_dict[key], 'error_mapping', None)
if error_mapping is not None:
......@@ -2521,7 +2521,7 @@ class ListBoxHTMLRendererLine(ListBoxRendererLine):
html += u' <span class="error">%s</span>' % error_message
else:
# If not editable, show a static text with a link, if enabled.
html = cgi.escape(processed_value)
html = html_quote(processed_value)
if url is not None:
# JPS-XXX - I think we should not display a URL for objects
# which do not have the View permission
......
......@@ -37,7 +37,7 @@ from Products.ERP5Type.Message import translateString
from AccessControl import ClassSecurityInfo
from Products.Formulator.DummyField import fields
from Products.ERP5Type.Globals import get_request
from cgi import escape
from Products.PythonScripts.standard import html_quote
import json
# Max. number of catalog result
......@@ -311,8 +311,8 @@ class MultiRelationStringFieldWidget(Widget.LinesTextAreaWidget,
value = value,
html_string = '<br />'.join(
'<a class="relationfieldlink" href="%s">%s</a>' % (
escape(jump_reference.absolute_url()),
escape(display_value),
html_quote(jump_reference.absolute_url()),
html_quote(display_value),
)
for jump_reference, display_value in zip(
getattr(
......@@ -345,7 +345,7 @@ class MultiRelationStringFieldWidget(Widget.LinesTextAreaWidget,
css_class = field.get_value('css_class')
if css_class not in ('', None):
html_string = '<span class="%s">%s</span>' % (
escape(css_class),
html_quote(css_class),
html_string,
)
return html_string
......@@ -363,9 +363,9 @@ $(document).ready(function() {
search_catalog_key: "%s"});
});
</script>""" % (
escape(key),
escape(json.dumps([x[0] for x in field.get_value('portal_type')])),
escape(field.get_value('catalog_index')),
html_quote(key),
html_quote(json.dumps([x[0] for x in field.get_value('portal_type')])),
html_quote(field.get_value('catalog_index')),
)
def render_wheel(self, field, value, REQUEST, relation_index=0,
......@@ -383,10 +383,10 @@ $(document).ready(function() {
'src="%s/images/exec16.png" alt="update..." ' \
'name="%s/viewSearchRelatedDocumentDialog%s%s' \
':method"/>' % (
escape(portal_url()),
escape(portal_url.getRelativeContentURL(here.portal_selections)),
escape(str(relation_index)),
escape(sub_index_string),
html_quote(portal_url()),
html_quote(portal_url.getRelativeContentURL(here.portal_selections)),
html_quote(str(relation_index)),
html_quote(sub_index_string),
)
def render_relation_link(self, field, value, REQUEST, render_prefix=None):
......@@ -408,8 +408,8 @@ $(document).ready(function() {
selection_name = REQUEST.get('selection_name')
if selection_name is not None:
selection_name_html = '&amp;selection_name=%s&amp;selection_index=%s' % (
escape(selection_name),
escape(str(REQUEST.get('selection_index', 0))),
html_quote(selection_name),
html_quote(str(REQUEST.get('selection_index', 0))),
)
else:
selection_name_html = ''
......@@ -420,12 +420,12 @@ $(document).ready(function() {
return '<a href="%s/%s?field_id=%s&amp;form_id=%s%s">' \
'<img src="%s/images/jump.png" alt="jump" />' \
'</a>' % (
escape(here.absolute_url()),
escape(field.get_value('jump_method')),
escape(field.id),
escape(field.aq_parent.id),
escape(selection_name_html),
escape(here.getPortalObject().portal_url()),
html_quote(here.absolute_url()),
html_quote(field.get_value('jump_method')),
html_quote(field.id),
html_quote(field.aq_parent.id),
html_quote(selection_name_html),
html_quote(here.getPortalObject().portal_url()),
)
return ''
......
......@@ -36,7 +36,6 @@ from Products.CMFCore.WorkflowCore import WorkflowException
from Products.CMFCore.CatalogTool import CatalogTool as CMFCoreCatalogTool
from Products.CMFActivity.Errors import ActivityPendingError
from cgi import escape
import sys
_marker = object()
......
......@@ -18,7 +18,7 @@ Close properly the <input /> tag
import ZTUtils.Zope
from ZTUtils.Zope import complex_marshal
import cgi
from Products.PythonScripts.standard import html_quote
from Products.ERP5Type.Utils import ensure_list
def make_hidden_input(*args, **kwargs):
......@@ -39,7 +39,7 @@ def make_hidden_input(*args, **kwargs):
d.update(arg)
d.update(kwargs)
hq = lambda x:cgi.escape(x, quote=True)
hq = lambda x: html_quote(x)
qlist = complex_marshal(ensure_list(d.items()))
for i in range(len(qlist)):
k, m, v = qlist[i]
......
......@@ -6,7 +6,7 @@ import string
from .DummyField import fields
from DocumentTemplate.DT_Util import html_quote
from DateTime import DateTime, Timezones
from cgi import escape
from Products.PythonScripts.standard import html_quote
import types
from DocumentTemplate.ustr import ustr
from six.moves.urllib.parse import urljoin
......@@ -441,7 +441,7 @@ class TextWidget(Widget):
old_value = [str(value)]
value = []
for line in old_value:
value.append(escape(line))
value.append(html_quote(line))
value = '<br/>'.join(value)
extra = field.get_value('extra')
......@@ -686,7 +686,7 @@ class TextAreaWidget(Widget):
value = str(value)
value = value.split('\n')
line_separator = '<br/>'
value_list = [escape(part).replace('\n', line_separator) for part in value]
value_list = [html_quote(part).replace('\n', line_separator) for part in value]
value = line_separator.join(value_list)
return render_element("div",
css_class=field.get_value('css_class'),
......@@ -751,7 +751,7 @@ class LinesTextAreaWidget(TextAreaWidget):
value = value.split('\n')
line_separator = field.get_value('view_separator')
value_list = [escape(convertToString(part)).replace('\n', line_separator) for part in value]
value_list = [html_quote(convertToString(part)).replace('\n', line_separator) for part in value]
value = line_separator.join(value_list)
return render_element("div",
css_class=field.get_value('css_class'),
......@@ -898,14 +898,14 @@ class SingleItemsWidget(ItemsWidget):
item_value = item
if item_value == value and not selected_found:
rendered_item = self.render_selected_item(escape(ustr(item_text)),
rendered_item = self.render_selected_item(html_quote(ustr(item_text)),
item_value,
key,
css_class,
extra_item)
selected_found = 1
else:
rendered_item = self.render_item(escape(ustr(item_text)),
rendered_item = self.render_item(html_quote(ustr(item_text)),
item_value,
key,
css_class,
......@@ -915,7 +915,7 @@ class SingleItemsWidget(ItemsWidget):
# XXX We want to make sure that we always have the current value in items. -yo
if not selected_found and value:
value = escape(ustr(value))
value = html_quote(ustr(value))
rendered_item = self.render_selected_item('??? (%s)' % value,
value,
key,
......@@ -934,7 +934,7 @@ class SingleItemsWidget(ItemsWidget):
return ''
title_list = [x[0] for x in field.get_value("items", REQUEST=REQUEST) if x[1]==value]
if len(title_list) == 0:
return "??? (%s)" % escape(value)
return "??? (%s)" % html_quote(value)
else:
return title_list[0]
return value
......@@ -1029,7 +1029,7 @@ class MultiItemsWidget(ItemsWidget):
if item_value in value:
rendered_item = self.render_selected_item(
escape(ustr(item_text)),
html_quote(ustr(item_text)),
item_value,
key,
css_class,
......@@ -1039,7 +1039,7 @@ class MultiItemsWidget(ItemsWidget):
selected_found[index] = 1
else:
rendered_item = self.render_item(
escape(ustr(item_text)),
html_quote(ustr(item_text)),
item_value,
key,
css_class,
......@@ -1050,7 +1050,7 @@ class MultiItemsWidget(ItemsWidget):
for index in range(len(value)):
v = value[index]
if index not in selected_found and v:
v = escape(v)
v = html_quote(v)
rendered_item = self.render_selected_item('??? (%s)' % v,
v,
key,
......
......@@ -13,7 +13,7 @@
##############################################################################
import operator
from cgi import escape
from Products.PythonScripts.standard import html_quote
from itertools import chain, islice
import six
try:
......@@ -309,8 +309,8 @@ class HBTreeFolder2Base (Persistent):
formatted = [listtext0 % pref_rows]
for optID in islice(self.objectIds(), b_start - 1, b_end):
optID = escape(optID)
formatted.append(listtext1 % (escape(optID, quote=1), optID))
optID = html_quote(optID)
formatted.append(listtext1 % (html_quote(optID), optID))
formatted.append(listtext2)
return {'b_start': b_start, 'b_end': b_end,
'prev_batch_url': prev_url,
......
......@@ -3,7 +3,7 @@ from six import unichr
from zLOG import ERROR
from six.moves.html_parser import HTMLParser
import re
from cgi import escape
from Products.PythonScripts.standard import html_quote
import codecs
from Products.PortalTransforms.interfaces import ITransform
......@@ -220,7 +220,7 @@ class StrippingParser(HTMLParser):
def handle_data(self, data):
if self.suppress: return
data = escape(data)
data = html_quote(data)
if self.original_charset and isinstance(data, str):
data = data.decode(self.original_charset)
self.result.append(data)
......@@ -294,7 +294,7 @@ class StrippingParser(HTMLParser):
self.original_charset = charset
v = charset_parser.sub(
CharsetReplacer(self.default_encoding), v)
self.result.append(' %s="%s"' % (k, escape(v, True)))
self.result.append(' %s="%s"' % (k, html_quote(v, True)))
Please register or sign in to reply
#UNUSED endTag = '</%s>' % tag
if safeToInt(self.valid.get(tag)):
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment