Merge branch 'alanhamlett-master'

Fix #1515
This commit is contained in:
Markus Unterwaditzer 2015-07-04 23:42:12 +02:00
commit db09c6798e
7 changed files with 49 additions and 13 deletions

View file

@ -68,6 +68,8 @@ Version 1.0
handlers (pull request ``#1393``). handlers (pull request ``#1393``).
- Allow custom Jinja environment subclasses (pull request ``#1422``). - Allow custom Jinja environment subclasses (pull request ``#1422``).
- ``flask.g`` now has ``pop()`` and ``setdefault`` methods. - ``flask.g`` now has ``pop()`` and ``setdefault`` methods.
- Turn on autoescape for ``flask.templating.render_template_string`` by default
(pull request ``#1515``).
Version 0.10.2 Version 0.10.2
-------------- --------------

View file

@ -18,7 +18,10 @@ Jinja Setup
Unless customized, Jinja2 is configured by Flask as follows: Unless customized, Jinja2 is configured by Flask as follows:
- autoescaping is enabled for all templates ending in ``.html``, - autoescaping is enabled for all templates ending in ``.html``,
``.htm``, ``.xml`` as well as ``.xhtml`` ``.htm``, ``.xml`` as well as ``.xhtml`` when using
:func:`~flask.templating.render_template`.
- autoescaping is enabled for all strings when using
:func:`~flask.templating.render_template_string`.
- a template has the ability to opt in/out autoescaping with the - a template has the ability to opt in/out autoescaping with the
``{% autoescape %}`` tag. ``{% autoescape %}`` tag.
- Flask inserts a couple of global functions and helpers into the - Flask inserts a couple of global functions and helpers into the

View file

@ -37,6 +37,10 @@ Now the inheritance hierarchy takes precedence and handlers for more
specific exception classes are executed instead of more general ones. specific exception classes are executed instead of more general ones.
See :ref:`error-handlers` for specifics. See :ref:`error-handlers` for specifics.
The :func:`~flask.templating.render_template_string` function has changed to
autoescape template variables by default. This better matches the behavior
of :func:`~flask.templating.render_template`.
.. note:: .. note::
There used to be a logic error allowing you to register handlers There used to be a logic error allowing you to register handlers

View file

@ -724,12 +724,12 @@ class Flask(_PackageBoundObject):
def select_jinja_autoescape(self, filename): def select_jinja_autoescape(self, filename):
"""Returns ``True`` if autoescaping should be active for the given """Returns ``True`` if autoescaping should be active for the given
template name. template name. If no template name is given, returns `True`.
.. versionadded:: 0.5 .. versionadded:: 0.5
""" """
if filename is None: if filename is None:
return False return True
return filename.endswith(('.html', '.htm', '.xml', '.xhtml')) return filename.endswith(('.html', '.htm', '.xml', '.xhtml'))
def update_template_context(self, context): def update_template_context(self, context):
@ -1090,14 +1090,14 @@ class Flask(_PackageBoundObject):
exc_class = default_exceptions[exc_class_or_code] exc_class = default_exceptions[exc_class_or_code]
else: else:
exc_class = exc_class_or_code exc_class = exc_class_or_code
assert issubclass(exc_class, Exception) assert issubclass(exc_class, Exception)
if issubclass(exc_class, HTTPException): if issubclass(exc_class, HTTPException):
return exc_class, exc_class.code return exc_class, exc_class.code
else: else:
return exc_class, None return exc_class, None
@setupmethod @setupmethod
def errorhandler(self, code_or_exception): def errorhandler(self, code_or_exception):
"""A decorator that is used to register a function give a given """A decorator that is used to register a function give a given
@ -1166,9 +1166,9 @@ class Flask(_PackageBoundObject):
'Tried to register a handler for an exception instance {0!r}. ' 'Tried to register a handler for an exception instance {0!r}. '
'Handlers can only be registered for exception classes or HTTP error codes.' 'Handlers can only be registered for exception classes or HTTP error codes.'
.format(code_or_exception)) .format(code_or_exception))
exc_class, code = self._get_exc_class_and_code(code_or_exception) exc_class, code = self._get_exc_class_and_code(code_or_exception)
handlers = self.error_handler_spec.setdefault(key, {}).setdefault(code, {}) handlers = self.error_handler_spec.setdefault(key, {}).setdefault(code, {})
handlers[exc_class] = f handlers[exc_class] = f
@ -1460,7 +1460,7 @@ class Flask(_PackageBoundObject):
# those unchanged as errors # those unchanged as errors
if e.code is None: if e.code is None:
return e return e
handler = self._find_error_handler(e) handler = self._find_error_handler(e)
if handler is None: if handler is None:
return e return e
@ -1503,12 +1503,12 @@ class Flask(_PackageBoundObject):
# wants the traceback preserved in handle_http_exception. Of course # wants the traceback preserved in handle_http_exception. Of course
# we cannot prevent users from trashing it themselves in a custom # we cannot prevent users from trashing it themselves in a custom
# trap_http_exception method so that's their fault then. # trap_http_exception method so that's their fault then.
if isinstance(e, HTTPException) and not self.trap_http_exception(e): if isinstance(e, HTTPException) and not self.trap_http_exception(e):
return self.handle_http_exception(e) return self.handle_http_exception(e)
handler = self._find_error_handler(e) handler = self._find_error_handler(e)
if handler is None: if handler is None:
reraise(exc_type, exc_value, tb) reraise(exc_type, exc_value, tb)
return handler(e) return handler(e)

View file

@ -127,7 +127,7 @@ def render_template(template_name_or_list, **context):
def render_template_string(source, **context): def render_template_string(source, **context):
"""Renders a template from the given template source string """Renders a template from the given template source string
with the given context. with the given context. Template variables will be autoescaped.
:param source: the source code of the template to be :param source: the source code of the template to be
rendered rendered

View file

@ -0,0 +1,8 @@
{{ text }}
{{ html }}
{% autoescape false %}{{ text }}
{{ html }}{% endautoescape %}
{% autoescape true %}{{ text }}
{{ html }}{% endautoescape %}
{{ text }}
{{ html }}

View file

@ -81,10 +81,29 @@ def test_escaping():
] ]
def test_no_escaping(): def test_no_escaping():
text = '<p>Hello World!'
app = flask.Flask(__name__)
@app.route('/')
def index():
return flask.render_template('non_escaping_template.txt', text=text,
html=flask.Markup(text))
lines = app.test_client().get('/').data.splitlines()
assert lines == [
b'<p>Hello World!',
b'<p>Hello World!',
b'<p>Hello World!',
b'<p>Hello World!',
b'&lt;p&gt;Hello World!',
b'<p>Hello World!',
b'<p>Hello World!',
b'<p>Hello World!'
]
def test_escaping_without_template_filename():
app = flask.Flask(__name__) app = flask.Flask(__name__)
with app.test_request_context(): with app.test_request_context():
assert flask.render_template_string( assert flask.render_template_string(
'{{ foo }}', foo='<test>') == '<test>' '{{ foo }}', foo='<test>') == '&lt;test&gt;'
assert flask.render_template('mail.txt', foo='<test>') == \ assert flask.render_template('mail.txt', foo='<test>') == \
'<test> Mail' '<test> Mail'