1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
|
import pytest
from webob.util import html_escape
from webob.compat import (
text_,
PY3
)
py2only = pytest.mark.skipif("sys.version_info >= (3, 0)")
py3only = pytest.mark.skipif("sys.version_info < (3, 0)")
class t_esc_HTML(object):
def __html__(self):
return '<div>hello</div>'
class t_esc_Unicode(object):
def __unicode__(self):
return text_(b'\xe9')
class t_esc_UnsafeAttrs(object):
attr = 'value'
def __getattr__(self, k):
return self.attr
def __repr__(self):
return '<UnsafeAttrs>'
class t_esc_SuperMoose(object):
def __str__(self):
return text_(b'm\xf8ose').encode('utf-8')
def __unicode__(self):
return text_(b'm\xf8ose')
@pytest.mark.parametrize("input,expected", [
('these chars: < > & "', 'these chars: < > & "'),
(' ', ' '),
('è', '&egrave;'),
# The apostrophe is *not* escaped, which some might consider to be
# a serious bug (see, e.g. http://www.cvedetails.com/cve/CVE-2010-2480/)
pytest.param("'", "'", marks=py2only),
pytest.param("'", "'", marks=py3only),
(text_('the majestic m\xf8ose'), 'the majestic møose'),
# 8-bit strings are passed through
(text_('\xe9'), 'é'),
# ``None`` is treated specially, and returns the empty string.
(None, ''),
# Objects that define a ``__html__`` method handle their own escaping
(t_esc_HTML(), '<div>hello</div>'),
# Things that are not strings are converted to strings and then escaped
(42, '42'),
# If an object implements both ``__str__`` and ``__unicode__``, the latter
# is preferred
(t_esc_SuperMoose(), 'møose'),
(t_esc_Unicode(), 'é'),
(t_esc_UnsafeAttrs(), '<UnsafeAttrs>'),
pytest.param(Exception("expected a '<'."), "expected a '<'.", marks=py2only),
pytest.param(
Exception("expected a '<'."),
"expected a '<'.",
marks=py3only
),
])
def test_html_escape(input, expected):
assert expected == html_escape(input)
|