diff --git a/template-engine/templite.py b/template-engine/templite.py index 0cf7651f1..8071a922a 100644 --- a/template-engine/templite.py +++ b/template-engine/templite.py @@ -165,7 +165,11 @@ def flush_output(): code.indent() elif words[0].startswith('end'): # Endsomething. Pop the ops stack. + if len(words) != 1: + self._syntax_error("Don't understand end", token) end_what = words[0][3:] + if not ops_stack: + self._syntax_error("Too many ends", token) start_what = ops_stack.pop() if start_what != end_what: self._syntax_error("Mismatched end tag", end_what) @@ -177,14 +181,14 @@ def flush_output(): if token: buffered.append(repr(token)) + if ops_stack: + self._syntax_error("Unmatched action tag", ops_stack[-1]) + flush_output() for var_name in self.all_vars - self.loop_vars: vars_code.add_line("c_%s = ctx[%r]" % (var_name, var_name)) - if ops_stack: - self._syntax_error("Unmatched action tag", ops_stack[-1]) - code.add_line("return ''.join(result)") code.dedent() self._render_function = code.get_globals()['render'] diff --git a/template-engine/test_templite.py b/template-engine/test_templite.py index 3c0d2d453..d821677c6 100644 --- a/template-engine/test_templite.py +++ b/template-engine/test_templite.py @@ -1,5 +1,6 @@ """Tests for templite.""" +import re from templite import Templite, TempliteSyntaxError from unittest import TestCase @@ -32,7 +33,8 @@ def try_render(self, text, ctx=None, result=None): self.assertEqual(actual, result) def assertSynErr(self, msg): - return self.assertRaisesRegexp(TempliteSyntaxError, msg) + pat = "^" + re.escape(msg) + "$" + return self.assertRaisesRegexp(TempliteSyntaxError, pat) def test_passthrough(self): # Strings without variables are passed through unchanged. @@ -250,7 +252,7 @@ def test_malformed_if(self): with self.assertSynErr("Don't understand if: '{% if this or that %}'"): self.try_render("Buh? {% if this or that %}hi!{% endif %}") - def test_malformed_for_(self): + def test_malformed_for(self): with self.assertSynErr("Don't understand for: '{% for %}'"): self.try_render("Weird: {% for %}loop{% endfor %}") with self.assertSynErr("Don't understand for: '{% for x from y %}'"): @@ -263,3 +265,11 @@ def test_bad_nesting(self): self.try_render("{% if x %}X") with self.assertSynErr("Mismatched end tag: 'for'"): self.try_render("{% if x %}X{% endfor %}") + with self.assertSynErr("Too many ends: '{% endif %}'"): + self.try_render("{% if x %}{% endif %}{% endif %}") + + def test_malformed_end(self): + with self.assertSynErr("Don't understand end: '{% end if %}'"): + self.try_render("{% if x %}X{% end if %}") + with self.assertSynErr("Don't understand end: '{% endif now %}'"): + self.try_render("{% if x %}X{% endif now %}")