From e4f635f8d7bade2dbd8b7e3e8be6df41e058c797 Mon Sep 17 00:00:00 2001 From: Alan Hamlett Date: Tue, 30 Jun 2015 10:59:25 -0700 Subject: [PATCH 1/2] remove whitespace at end of lines --- flask/app.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/flask/app.py b/flask/app.py index 668f36ce..dae6b24e 100644 --- a/flask/app.py +++ b/flask/app.py @@ -1090,14 +1090,14 @@ class Flask(_PackageBoundObject): exc_class = default_exceptions[exc_class_or_code] else: exc_class = exc_class_or_code - + assert issubclass(exc_class, Exception) - + if issubclass(exc_class, HTTPException): return exc_class, exc_class.code else: return exc_class, None - + @setupmethod def errorhandler(self, code_or_exception): """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}. ' 'Handlers can only be registered for exception classes or HTTP error codes.' .format(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[exc_class] = f @@ -1460,7 +1460,7 @@ class Flask(_PackageBoundObject): # those unchanged as errors if e.code is None: return e - + handler = self._find_error_handler(e) if handler is None: return e @@ -1503,12 +1503,12 @@ class Flask(_PackageBoundObject): # wants the traceback preserved in handle_http_exception. Of course # we cannot prevent users from trashing it themselves in a custom # trap_http_exception method so that's their fault then. - + if isinstance(e, HTTPException) and not self.trap_http_exception(e): return self.handle_http_exception(e) handler = self._find_error_handler(e) - + if handler is None: reraise(exc_type, exc_value, tb) return handler(e) From 99c99c4c16b1327288fd76c44bc8635a1de452bc Mon Sep 17 00:00:00 2001 From: Alan Hamlett Date: Tue, 30 Jun 2015 11:00:14 -0700 Subject: [PATCH 2/2] Enable autoescape for `render_template_string` --- CHANGES | 2 ++ docs/templating.rst | 5 ++++- docs/upgrading.rst | 4 ++++ flask/app.py | 4 ++-- flask/templating.py | 2 +- tests/templates/non_escaping_template.txt | 8 ++++++++ tests/test_templating.py | 21 ++++++++++++++++++++- 7 files changed, 41 insertions(+), 5 deletions(-) create mode 100644 tests/templates/non_escaping_template.txt diff --git a/CHANGES b/CHANGES index 8310761f..b33c3795 100644 --- a/CHANGES +++ b/CHANGES @@ -68,6 +68,8 @@ Version 1.0 handlers (pull request ``#1393``). - Allow custom Jinja environment subclasses (pull request ``#1422``). - ``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 -------------- diff --git a/docs/templating.rst b/docs/templating.rst index a8c8d0a9..11d5d48d 100644 --- a/docs/templating.rst +++ b/docs/templating.rst @@ -18,7 +18,10 @@ Jinja Setup Unless customized, Jinja2 is configured by Flask as follows: - 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 ``{% autoescape %}`` tag. - Flask inserts a couple of global functions and helpers into the diff --git a/docs/upgrading.rst b/docs/upgrading.rst index b0460b38..fca4d75b 100644 --- a/docs/upgrading.rst +++ b/docs/upgrading.rst @@ -37,6 +37,10 @@ Now the inheritance hierarchy takes precedence and handlers for more specific exception classes are executed instead of more general ones. 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:: There used to be a logic error allowing you to register handlers diff --git a/flask/app.py b/flask/app.py index dae6b24e..f0a8b69b 100644 --- a/flask/app.py +++ b/flask/app.py @@ -724,12 +724,12 @@ class Flask(_PackageBoundObject): def select_jinja_autoescape(self, filename): """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 """ if filename is None: - return False + return True return filename.endswith(('.html', '.htm', '.xml', '.xhtml')) def update_template_context(self, context): diff --git a/flask/templating.py b/flask/templating.py index 59fd988e..8c95a6a7 100644 --- a/flask/templating.py +++ b/flask/templating.py @@ -127,7 +127,7 @@ def render_template(template_name_or_list, **context): def render_template_string(source, **context): """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 rendered diff --git a/tests/templates/non_escaping_template.txt b/tests/templates/non_escaping_template.txt new file mode 100644 index 00000000..542864e8 --- /dev/null +++ b/tests/templates/non_escaping_template.txt @@ -0,0 +1,8 @@ +{{ text }} +{{ html }} +{% autoescape false %}{{ text }} +{{ html }}{% endautoescape %} +{% autoescape true %}{{ text }} +{{ html }}{% endautoescape %} +{{ text }} +{{ html }} diff --git a/tests/test_templating.py b/tests/test_templating.py index 293ca06f..b60a592a 100644 --- a/tests/test_templating.py +++ b/tests/test_templating.py @@ -81,10 +81,29 @@ def test_escaping(): ] def test_no_escaping(): + text = '

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'

Hello World!', + b'

Hello World!', + b'

Hello World!', + b'

Hello World!', + b'<p>Hello World!', + b'

Hello World!', + b'

Hello World!', + b'

Hello World!' + ] + +def test_escaping_without_template_filename(): app = flask.Flask(__name__) with app.test_request_context(): assert flask.render_template_string( - '{{ foo }}', foo='') == '' + '{{ foo }}', foo='') == '<test>' assert flask.render_template('mail.txt', foo='') == \ ' Mail'