From 4e6f9a254910ce3524ea9a1c9bfb6feb54716f01 Mon Sep 17 00:00:00 2001 From: Armin Ronacher <armin.ronacher@active-4.com> Date: Fri, 23 May 2008 23:57:38 +0200 Subject: [PATCH] added unittest for Markup and let the markup constructor accept `__html__` objects --HG-- branch : trunk --- jinja2/filters.py | 2 +- jinja2/utils.py | 5 +++++ tests/test_filters.py | 31 +++++++++++++++++++------------ tests/test_security.py | 31 +++++++++++++++++++++++++++++++ 4 files changed, 56 insertions(+), 13 deletions(-) diff --git a/jinja2/filters.py b/jinja2/filters.py index 94086a6..2cbb46c 100644 --- a/jinja2/filters.py +++ b/jinja2/filters.py @@ -74,7 +74,7 @@ def do_replace(environment, s, old, new, count=None): s = escape(s) else: s = soft_unicode(s) - return s.replace(old, new, count) + return s.replace(soft_unicode(old), soft_unicode(new), count) def do_upper(s): diff --git a/jinja2/utils.py b/jinja2/utils.py index 90eb737..2a671d0 100644 --- a/jinja2/utils.py +++ b/jinja2/utils.py @@ -234,6 +234,11 @@ class Markup(unicode): """ __slots__ = () + def __new__(cls, base=u''): + if hasattr(base, '__html__'): + base = base.__html__() + return unicode.__new__(cls, base) + def __html__(self): return self diff --git a/tests/test_filters.py b/tests/test_filters.py index 6592027..559b0b1 100644 --- a/tests/test_filters.py +++ b/tests/test_filters.py @@ -3,17 +3,11 @@ unit test for the filters ~~~~~~~~~~~~~~~~~~~~~~~~~ - Missing tests: - - - wordcount - - rst - - markdown - - textile - - :copyright: 2007 by Armin Ronacher. + :copyright: 2008 by Armin Ronacher. :license: BSD, see LICENSE for more details. """ -from jinja2 import Markup +from jinja2 import Markup, Environment + CAPITALIZE = '''{{ "foo bar"|capitalize }}''' CENTER = '''{{ "foo"|center(9) }}''' @@ -164,6 +158,10 @@ def test_join(env): out = tmpl.render() assert out == '1|2|3' + env2 = Environment(autoescape=True) + tmpl = env2.from_string('{{ ["<foo>", "<span>foo</span>"|safe]|join }}') + assert tmpl.render() == '<foo><span>foo</span>' + def test_last(env): tmpl = env.from_string(LAST) @@ -293,9 +291,18 @@ def test_filtertag(env): assert tmpl.render() == 'fooBAR' -def test_replace(env): - tmpl = env.from_string('{{ "foo"|replace("o", 42)}}') - assert tmpl.render() == 'f4242' +def test_replace(): + env = Environment() + tmpl = env.from_string('{{ string|replace("o", 42) }}') + assert tmpl.render(string='<foo>') == '<f4242>' + + env = Environment(autoescape=True) + tmpl = env.from_string('{{ string|replace("o", 42) }}') + assert tmpl.render(string='<foo>') == '<f4242>' + tmpl = env.from_string('{{ string|replace("<", 42) }}') + assert tmpl.render(string='<foo>') == '42foo>' + tmpl = env.from_string('{{ string|replace("o", ">x<") }}') + assert tmpl.render(string=Markup('foo')) == 'f>x<>x<' def test_forceescape(env): diff --git a/tests/test_security.py b/tests/test_security.py index 5974e1f..0cacf5f 100644 --- a/tests/test_security.py +++ b/tests/test_security.py @@ -8,6 +8,7 @@ """ from jinja2.sandbox import SandboxedEnvironment, \ ImmutableSandboxedEnvironment, unsafe +from jinja2 import Markup, escape class PrivateStuff(object): @@ -82,3 +83,33 @@ Traceback (most recent call last): ... SecurityError: access to attribute 'clear' of 'dict' object is unsafe. ''' + +def test_markup_operations(): + # adding two strings should escape the unsafe one + unsafe = '<script type="application/x-some-script">alert("foo");</script>' + safe = Markup('<em>username</em>') + assert unsafe + safe == unicode(escape(unsafe)) + unicode(safe) + + # string interpolations are safe to use too + assert Markup('<em>%s</em>') % '<bad user>' == \ + '<em><bad user></em>' + assert Markup('<em>%(username)s</em>') % { + 'username': '<bad user>' + } == '<em><bad user></em>' + + # an escaped object is markup too + assert type(Markup('foo') + 'bar') is Markup + + # and it implements __html__ by returning itself + x = Markup("foo") + assert x.__html__() is x + + # it also knows how to treat __html__ objects + class Foo(object): + def __html__(self): + return '<em>awesome</em>' + def __unicode__(self): + return 'awesome' + assert Markup(Foo()) == '<em>awesome</em>' + assert Markup('<strong>%s</strong>') % Foo() == \ + '<strong><em>awesome</em></strong>' -- 2.26.2