[FIX] P3: remove cgi.escape uses
cgi.escape is unsafe (quote=False by default) and deprecated in Python 3. We already have an openerp.tools.misc.html_escape version which forwards to the (modern and safe) werkzeug.utils.escape, just use that everywhere, and convert extant uses of werkzeug.utils.escape to utils.html_escape as well so that we do the same thing everywhere.
This commit is contained in:
@@ -1,11 +1,11 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
import cgi
|
||||
import json
|
||||
|
||||
from odoo import http
|
||||
from odoo.http import request
|
||||
from odoo.tools import misc
|
||||
|
||||
|
||||
class ImportController(http.Controller):
|
||||
@@ -20,4 +20,4 @@ class ImportController(http.Controller):
|
||||
'file_type': file.content_type,
|
||||
})
|
||||
|
||||
return 'window.top.%s(%s)' % (cgi.escape(jsonp), json.dumps({'result': written}))
|
||||
return 'window.top.%s(%s)' % (misc.html_escape(jsonp), json.dumps({'result': written}))
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
import cgi
|
||||
import json
|
||||
import logging
|
||||
|
||||
@@ -10,6 +9,7 @@ import re
|
||||
import werkzeug.urls
|
||||
|
||||
from odoo import api, models
|
||||
from odoo.tools import misc
|
||||
from odoo.addons.google_account import TIMEOUT
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
@@ -70,7 +70,7 @@ class GoogleDrive(models.Model):
|
||||
href="https://spreadsheets.google.com/feeds/cells/{key}/od6/private/full/R60C15"/>
|
||||
<gs:cell row="60" col="15" inputValue="{config}"/>
|
||||
</entry>
|
||||
</feed>''' .format(key=spreadsheet_key, formula=cgi.escape(formula, quote=True), config=cgi.escape(config_formula, quote=True))
|
||||
</feed>''' .format(key=spreadsheet_key, formula=misc.html_escape(formula), config=misc.html_escape(config_formula))
|
||||
|
||||
try:
|
||||
req = requests.post(
|
||||
|
||||
@@ -8,6 +8,7 @@ import werkzeug
|
||||
|
||||
import odoo
|
||||
from odoo import http
|
||||
from odoo.tools import misc
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -106,7 +107,7 @@ class PosboxHomepage(odoo.addons.web.controllers.main.Home):
|
||||
f = open('/tmp/scanned_networks.txt', 'r')
|
||||
for line in f:
|
||||
line = line.rstrip()
|
||||
line = werkzeug.utils.escape(line)
|
||||
line = misc.html_escape(line)
|
||||
wifi_template += '<option value="' + line + '">' + line + '</option>\n'
|
||||
f.close()
|
||||
except IOError:
|
||||
|
||||
@@ -3,15 +3,12 @@
|
||||
|
||||
from datetime import date, timedelta
|
||||
|
||||
import cgi
|
||||
import ssl
|
||||
|
||||
import requests
|
||||
import werkzeug
|
||||
|
||||
from odoo import models, api, service
|
||||
from odoo.exceptions import UserError
|
||||
from odoo.tools import DEFAULT_SERVER_DATETIME_FORMAT
|
||||
from odoo.tools import DEFAULT_SERVER_DATETIME_FORMAT, misc
|
||||
|
||||
|
||||
class MercuryTransaction(models.Model):
|
||||
@@ -53,7 +50,7 @@ class MercuryTransaction(models.Model):
|
||||
|
||||
soap_header = '<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:mer="http://www.mercurypay.com"><soapenv:Header/><soapenv:Body><mer:CreditTransaction><mer:tran>'
|
||||
soap_footer = '</mer:tran><mer:pw>' + data['merchant_pwd'] + '</mer:pw></mer:CreditTransaction></soapenv:Body></soapenv:Envelope>'
|
||||
xml_transaction = soap_header + cgi.escape(xml_transaction) + soap_footer
|
||||
xml_transaction = soap_header + misc.escape_html(xml_transaction) + soap_footer
|
||||
|
||||
response = ''
|
||||
|
||||
|
||||
@@ -12,7 +12,6 @@ from odoo import fields, tools
|
||||
from odoo.http import request
|
||||
from odoo.modules.module import get_resource_path
|
||||
import psycopg2
|
||||
import werkzeug
|
||||
from odoo.tools import func, misc, pycompat
|
||||
|
||||
import logging
|
||||
@@ -587,7 +586,7 @@ class StylesheetAsset(WebAsset):
|
||||
return self.with_header(content)
|
||||
|
||||
def to_html(self):
|
||||
media = (' media="%s"' % werkzeug.utils.escape(self.media)) if self.media else ''
|
||||
media = (' media="%s"' % misc.html_escape(self.media)) if self.media else ''
|
||||
if self.url:
|
||||
href = self.html_url
|
||||
return '<link rel="stylesheet" href="%s" type="text/css"%s/>' % (href, media)
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
import cgi
|
||||
import unittest
|
||||
|
||||
from odoo.tools import html_sanitize, append_content_to_html, plaintext2html, email_split
|
||||
from odoo.tools import html_sanitize, append_content_to_html, plaintext2html, email_split, misc
|
||||
from . import test_mail_examples
|
||||
|
||||
|
||||
@@ -99,7 +98,7 @@ class TestSanitizer(unittest.TestCase):
|
||||
"Div nico <div-nico@open.com>"
|
||||
]
|
||||
for email in emails:
|
||||
self.assertIn(cgi.escape(email), html_sanitize(email), 'html_sanitize stripped emails of original html')
|
||||
self.assertIn(misc.html_escape(email), html_sanitize(email), 'html_sanitize stripped emails of original html')
|
||||
|
||||
def test_sanitize_unescape_emails(self):
|
||||
not_emails = [
|
||||
@@ -108,7 +107,7 @@ class TestSanitizer(unittest.TestCase):
|
||||
for email in not_emails:
|
||||
sanitized = html_sanitize(email)
|
||||
left_part = email.split('>')[0] # take only left part, as the sanitizer could add data information on node
|
||||
self.assertNotIn(cgi.escape(email), sanitized, 'html_sanitize stripped emails of original html')
|
||||
self.assertNotIn(misc.html_escape(email), sanitized, 'html_sanitize stripped emails of original html')
|
||||
self.assertIn(left_part, sanitized)
|
||||
|
||||
def test_style_parsing(self):
|
||||
@@ -172,14 +171,14 @@ class TestSanitizer(unittest.TestCase):
|
||||
for ext in test_mail_examples.QUOTE_BLOCKQUOTE_IN:
|
||||
self.assertIn(ext, html)
|
||||
for ext in test_mail_examples.QUOTE_BLOCKQUOTE_OUT:
|
||||
self.assertIn('<span data-o-mail-quote="1">%s' % cgi.escape(ext.decode('utf-8')), html)
|
||||
self.assertIn('<span data-o-mail-quote="1">%s' % misc.html_escape(ext.decode('utf-8')), html)
|
||||
|
||||
def test_quote_thunderbird(self):
|
||||
html = html_sanitize(test_mail_examples.QUOTE_THUNDERBIRD_1)
|
||||
for ext in test_mail_examples.QUOTE_THUNDERBIRD_1_IN:
|
||||
self.assertIn(ext, html)
|
||||
for ext in test_mail_examples.QUOTE_THUNDERBIRD_1_OUT:
|
||||
self.assertIn('<span data-o-mail-quote="1">%s</span>' % cgi.escape(ext.decode('utf-8')), html)
|
||||
self.assertIn('<span data-o-mail-quote="1">%s</span>' % misc.html_escape(ext.decode('utf-8')), html)
|
||||
|
||||
def test_quote_hotmail_html(self):
|
||||
html = html_sanitize(test_mail_examples.QUOTE_HOTMAIL_HTML)
|
||||
@@ -226,7 +225,7 @@ class TestSanitizer(unittest.TestCase):
|
||||
for text in in_lst:
|
||||
self.assertIn(text, new_html)
|
||||
for text in out_lst:
|
||||
self.assertIn('<span data-o-mail-quote="1">%s</span>' % cgi.escape(text), new_html)
|
||||
self.assertIn('<span data-o-mail-quote="1">%s</span>' % misc.html_escape(text), new_html)
|
||||
|
||||
def test_quote_signature(self):
|
||||
test_data = [
|
||||
@@ -245,27 +244,27 @@ class TestSanitizer(unittest.TestCase):
|
||||
for ext in test_mail_examples.GMAIL_1_IN:
|
||||
self.assertIn(ext, html)
|
||||
for ext in test_mail_examples.GMAIL_1_OUT:
|
||||
self.assertIn('<span data-o-mail-quote="1">%s</span>' % cgi.escape(ext), html)
|
||||
self.assertIn('<span data-o-mail-quote="1">%s</span>' % misc.html_escape(ext), html)
|
||||
|
||||
def test_quote_text(self):
|
||||
html = html_sanitize(test_mail_examples.TEXT_1)
|
||||
for ext in test_mail_examples.TEXT_1_IN:
|
||||
self.assertIn(ext, html)
|
||||
for ext in test_mail_examples.TEXT_1_OUT:
|
||||
self.assertIn('<span data-o-mail-quote="1">%s</span>' % cgi.escape(ext), html)
|
||||
self.assertIn('<span data-o-mail-quote="1">%s</span>' % misc.html_escape(ext), html)
|
||||
|
||||
html = html_sanitize(test_mail_examples.TEXT_2)
|
||||
for ext in test_mail_examples.TEXT_2_IN:
|
||||
self.assertIn(ext, html)
|
||||
for ext in test_mail_examples.TEXT_2_OUT:
|
||||
self.assertIn('<span data-o-mail-quote="1">%s</span>' % cgi.escape(ext), html)
|
||||
self.assertIn('<span data-o-mail-quote="1">%s</span>' % misc.html_escape(ext), html)
|
||||
|
||||
def test_quote_bugs(self):
|
||||
html = html_sanitize(test_mail_examples.BUG1)
|
||||
for ext in test_mail_examples.BUG_1_IN:
|
||||
self.assertIn(ext, html)
|
||||
for ext in test_mail_examples.BUG_1_OUT:
|
||||
self.assertIn('<span data-o-mail-quote="1">%s</span>' % cgi.escape(ext.decode('utf-8')), html)
|
||||
self.assertIn('<span data-o-mail-quote="1">%s</span>' % misc.html_escape(ext.decode('utf-8')), html)
|
||||
|
||||
def test_misc(self):
|
||||
# False / void should not crash
|
||||
|
||||
@@ -1,19 +1,17 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
import cgi
|
||||
import collections
|
||||
import json
|
||||
import os.path
|
||||
import re
|
||||
|
||||
from lxml import etree
|
||||
from itertools import chain
|
||||
|
||||
from odoo.modules import get_module_resource
|
||||
from odoo.tests.common import TransactionCase
|
||||
from odoo.addons.base.ir.ir_qweb import QWebException
|
||||
from odoo.tools import pycompat
|
||||
from odoo.tools import pycompat, misc, ustr
|
||||
|
||||
|
||||
def dedent_and_strip(string):
|
||||
@@ -48,12 +46,12 @@ class TestQWebTField(TransactionCase):
|
||||
|
||||
result = self.engine.render(field, {'company': company})
|
||||
self.assertEqual(
|
||||
result,
|
||||
ustr(result),
|
||||
'<span data-oe-model="res.company" data-oe-id="%d" '
|
||||
'data-oe-field="name" data-oe-type="char" '
|
||||
'data-oe-expression="company.name">%s</span>' % (
|
||||
company.id,
|
||||
cgi.escape(s.encode('utf-8')),
|
||||
misc.html_escape(s),
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
+6
-7
@@ -1,7 +1,6 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
import cgi
|
||||
import logging
|
||||
import lxml.html.clean as clean
|
||||
import random
|
||||
@@ -16,7 +15,7 @@ from lxml import etree
|
||||
|
||||
import odoo
|
||||
from odoo.loglevels import ustr
|
||||
from odoo.tools import pycompat
|
||||
from odoo.tools import pycompat, misc
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -178,10 +177,10 @@ def html_sanitize(src, silent=True, sanitize_tags=True, sanitize_attributes=Fals
|
||||
part = re.compile(r"(<(([^a<>]|a[^<>\s])[^<>]*)@[^<>]+>)", re.IGNORECASE | re.DOTALL)
|
||||
# remove results containing cite="mid:email_like@address" (ex: blockquote cite)
|
||||
# cite_except = re.compile(r"^((?!cite[\s]*=['\"]).)*$", re.IGNORECASE)
|
||||
src = part.sub(lambda m: ('cite=' not in m.group(1) and 'alt=' not in m.group(1)) and cgi.escape(m.group(1)) or m.group(1), src)
|
||||
src = part.sub(lambda m: ('cite=' not in m.group(1) and 'alt=' not in m.group(1)) and misc.html_escape(m.group(1)) or m.group(1), src)
|
||||
# html encode mako tags <% ... %> to decode them later and keep them alive, otherwise they are stripped by the cleaner
|
||||
src = src.replace('<%', cgi.escape('<%'))
|
||||
src = src.replace('%>', cgi.escape('%>'))
|
||||
src = src.replace('<%', misc.html_escape('<%'))
|
||||
src = src.replace('%>', misc.html_escape('%>'))
|
||||
|
||||
kwargs = {
|
||||
'page_structure': True,
|
||||
@@ -334,7 +333,7 @@ def html2plaintext(html, body_id=None, encoding='utf-8'):
|
||||
|
||||
def plaintext2html(text, container_tag=False):
|
||||
""" Convert plaintext into html. Content of the text is escaped to manage
|
||||
html entities, using cgi.escape().
|
||||
html entities, using misc.html_escape().
|
||||
- all \n,\r are replaced by <br />
|
||||
- enclose content into <p>
|
||||
- convert url into clickable link
|
||||
@@ -343,7 +342,7 @@ def plaintext2html(text, container_tag=False):
|
||||
:param string container_tag: container of the html; by default the
|
||||
content is embedded into a <div>
|
||||
"""
|
||||
text = cgi.escape(ustr(text))
|
||||
text = misc.html_escape(ustr(text))
|
||||
|
||||
# 1. replace \n and \r
|
||||
text = text.replace('\n', '<br/>')
|
||||
|
||||
Reference in New Issue
Block a user