From: Armin Ronacher Date: Sat, 7 Jan 2017 15:13:39 +0000 (+0100) Subject: Updated docs on autoescaping and made select_autoescape case insensitive X-Git-Tag: 2.9~3 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b81a8a3e37bcc117fde391249eafdfae5a3f8869;p=thirdparty%2Fjinja.git Updated docs on autoescaping and made select_autoescape case insensitive --- diff --git a/docs/api.rst b/docs/api.rst index b7c25d39..de4d2e44 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -26,14 +26,18 @@ are in use. The simplest way to configure Jinja2 to load templates for your application looks roughly like this:: - from jinja2 import Environment, PackageLoader - env = Environment(loader=PackageLoader('yourapplication', 'templates')) + from jinja2 import Environment, PackageLoader, select_autoescape + env = Environment( + loader=PackageLoader('yourapplication', 'templates'), + autoescape=select_autoescape(['html', 'xml']) + ) This will create a template environment with the default settings and a loader that looks up the templates in the `templates` folder inside the `yourapplication` python package. Different loaders are available and you can also write your own if you want to load templates from a -database or other resources. +database or other resources. This also enables autoescaping for HTML and +XML files. To load a template from this environment you just have to call the :meth:`get_template` method which then returns the loaded :class:`Template`:: @@ -48,6 +52,12 @@ Using a template loader rather than passing strings to :class:`Template` or :meth:`Environment.from_string` has multiple advantages. Besides being a lot easier to use it also enables template inheritance. +.. admonition:: Notes on Autoescaping + + In future versions of Jinja2 we might enable autoescaping by default + for security reasons. As such you are encouraged to explicitly + configure autoescaping now instead of relying on the default. + Unicode ------- @@ -251,27 +261,34 @@ Autoescaping Jinja2 now comes with autoescaping support. As of Jinja 2.9 the autoescape extension is removed and built-in. However autoescaping is -not yet enabled by default though this might change in the future. -It's recommended to configure a sensible default for autoescaping. This -makes it possible to enable and disable autoescaping on a per-template -basis (HTML versus text for instance). +not yet enabled by default though this will most likely change in the +future. It's recommended to configure a sensible default for +autoescaping. This makes it possible to enable and disable autoescaping +on a per-template basis (HTML versus text for instance). + +.. autofunction:: jinja2.select_autoescape Here a recommended setup that enables autoescaping for templates ending in ``'.html'``, ``'.htm'`` and ``'.xml'`` and disabling it by default -for all other extensions:: - - def guess_autoescape(template_name): - if template_name is None or '.' not in template_name: - return False - ext = template_name.rsplit('.', 1)[1] - return ext in ('html', 'htm', 'xml') +for all other extensions. You can use the :func:`~jinja2.select_autoescape` +function for this:: - env = Environment(autoescape=guess_autoescape, + from jinja2 import Environment, select_autoescape + env = Environment(autoescape=select_autoescape(['html', 'htm', 'xml']), loader=PackageLoader('mypackage')) +The :func:`~jinja.select_autoescape` function returns a function that +works rougly like this:: + + def autoescape(template_name): + if template_name is None: + return False + if template_name.endswith(('.html', '.htm', '.xml')) + When implementing a guessing autoescape function, make sure you also accept `None` as valid template name. This will be passed when generating -templates from strings. +templates from strings. You should always configure autoescaping as +defaults in the future might change. Inside the templates the behaviour can be temporarily changed by using the `autoescape` block (see :ref:`autoescape-overrides`). diff --git a/jinja2/utils.py b/jinja2/utils.py index 9bab1434..0f04bdbc 100644 --- a/jinja2/utils.py +++ b/jinja2/utils.py @@ -522,13 +522,18 @@ def select_autoescape(enabled_extensions=('html', 'htm', 'xml'), If nothing matches then the initial value of autoescaping is set to the value of `default`. + For security reasons this function operates case insensitive. + .. versionadded:: 2.9 """ - enabled_patterns = tuple('.' + x.lstrip('.') for x in enabled_extensions) - disabled_patterns = tuple('.' + x.lstrip('.') for x in disabled_extensions) + enabled_patterns = tuple('.' + x.lstrip('.').lower() + for x in enabled_extensions) + disabled_patterns = tuple('.' + x.lstrip('.').lower() + for x in disabled_extensions) def autoescape(template_name): if template_name is None: return default_for_string + template_name = template_name.lower() if template_name.endswith(enabled_patterns): return True if template_name.endswith(disabled_patterns): diff --git a/tests/test_utils.py b/tests/test_utils.py index 0cae4d42..c2618028 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -71,6 +71,8 @@ class TestHelpers(object): assert func('foo.html') == True assert func('foo.htm') == True assert func('foo.txt') == False + assert func('FOO.HTML') == True + assert func('FOO.TXT') == False @pytest.mark.utils