From d5c293a4405e8e0fa4d31afcf8302f3b0e3a9f42 Mon Sep 17 00:00:00 2001 From: Pavlo Shchelokovskyy Date: Thu, 2 Apr 2020 08:24:08 +0300 Subject: [PATCH] Do not autoescape all Jinja2 templates this breaks pxe config rendering when e.g. quotes are needed (like for values with spaces), replacing them with HTML escape codes. Instead use smart autoescape which by default is only enabled for htm(l) and xml templates. Not specifically setting override for strings as we set the template name for string templates anyway, and matching goes by that name. https://jinja.palletsprojects.com/en/2.11.x/api/#autoescaping Change-Id: I27e63557d4bcd81d583c55315029425bec03fd98 Story: 2005791 Task: 39269 --- ironic/common/utils.py | 7 ++++++- ironic/tests/unit/common/test_utils.py | 9 +++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/ironic/common/utils.py b/ironic/common/utils.py index 12d57557e9..2d389af593 100644 --- a/ironic/common/utils.py +++ b/ironic/common/utils.py @@ -472,7 +472,12 @@ def render_template(template, params, is_file=True): else: tmpl_name = 'template' loader = jinja2.DictLoader({tmpl_name: template}) - env = jinja2.Environment(loader=loader, autoescape=True) + # NOTE(pas-ha) bandit does not seem to cope with such syntaxis + # and still complains with B701 for that line + # NOTE(pas-ha) not using default_for_string=False as we set the name + # of the template above for strings too. + env = jinja2.Environment(loader=loader, # nosec B701 + autoescape=jinja2.select_autoescape()) tmpl = env.get_template(tmpl_name) return tmpl.render(params, enumerate=enumerate) diff --git a/ironic/tests/unit/common/test_utils.py b/ironic/tests/unit/common/test_utils.py index 8d7b21aed0..0a652435de 100644 --- a/ironic/tests/unit/common/test_utils.py +++ b/ironic/tests/unit/common/test_utils.py @@ -535,6 +535,15 @@ class JinjaTemplatingTestCase(base.TestCase): self.params, is_file=False)) + def test_render_with_quotes(self): + """test jinja2 autoescaping for everything is disabled """ + self.expected = '"spam" ham' + self.params = {'foo': '"spam"', 'bar': 'ham'} + self.assertEqual(self.expected, + utils.render_template(self.template, + self.params, + is_file=False)) + @mock.patch('ironic.common.utils.jinja2.FileSystemLoader', autospec=True) def test_render_file(self, jinja_fsl_mock): path = '/path/to/template.j2'