Skip to content

Commit

Permalink
Drop-in html.escape in place of cgi.escape for python3.2+ (#1513)
Browse files Browse the repository at this point in the history
Fix #1330

Define `escape_html` function with signature same as for `cgi.escape` and `html.escape` having `quote=False` default param.
  • Loading branch information
paulohrpinheiro authored and webknjaz committed Nov 1, 2016
1 parent 98e4711 commit c65dc27
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 2 deletions.
16 changes: 16 additions & 0 deletions cherrypy/_cpcompat.py
Expand Up @@ -332,3 +332,19 @@ def _args_from_interpreter_flags():
args.append('-W' + opt)

return args

# html module come in 3.2 version
try:
from html import escape
except ImportError:
from cgi import escape

# html module needed the argument quote=False because in cgi the default
# is False. With quote=True the results differ.

def escape_html(s, escape_quote=False):
"""Replace special characters "&", "<" and ">" to HTML-safe sequences.
When escape_quote=True, escape (') and (") chars.
"""
return escape(s, quote=escape_quote)
4 changes: 2 additions & 2 deletions cherrypy/_cperror.py
Expand Up @@ -116,13 +116,13 @@ class Root:
"""

import contextlib
from cgi import escape as _escape
from sys import exc_info as _exc_info
from traceback import format_exception as _format_exception
from xml.sax import saxutils

import six

from cherrypy._cpcompat import escape_html
from cherrypy._cpcompat import text_or_bytes, iteritems, ntob
from cherrypy._cpcompat import tonative, urljoin as _urljoin
from cherrypy.lib import httputil as _httputil
Expand Down Expand Up @@ -502,7 +502,7 @@ def get_error_page(status, **kwargs):
if v is None:
kwargs[k] = ''
else:
kwargs[k] = _escape(kwargs[k])
kwargs[k] = escape_html(kwargs[k])

# Use a custom template or callable for the error page?
pages = cherrypy.serving.request.error_page
Expand Down
8 changes: 8 additions & 0 deletions cherrypy/test/test_compat.py
Expand Up @@ -21,3 +21,11 @@ def test_ntob_non_native(self):
if six.PY3:
raise nose.SkipTest('Only useful on Python 2')
self.assertRaises(Exception, compat.ntob, 'fight')


class EscapeTester(unittest.TestCase):
"""Class to test escape_html function from _cpcompat."""

def test_escape_quote(self):
"""test_escape_quote - Verify the output for &<>"' chars."""
self.assertEqual("""xx&amp;&lt;&gt;"aa'""", compat.escape_html("""xx&<>"aa'"""))

0 comments on commit c65dc27

Please sign in to comment.