diff --git a/CHANGES b/CHANGES
index 5f69137d8..65bf96916 100644
--- a/CHANGES
+++ b/CHANGES
@@ -27,6 +27,7 @@ Version 2.9
autoescaping information at call time instead of macro define time.
- Ported a modified version of the `tojson` filter from Flask to Jinja2
and hooked it up with the new policy framework.
+- Block sets are now marked `safe` by default.
Version 2.8.2
-------------
diff --git a/jinja2/compiler.py b/jinja2/compiler.py
index cc808e9d8..02ae30888 100644
--- a/jinja2/compiler.py
+++ b/jinja2/compiler.py
@@ -1297,7 +1297,8 @@ def visit_AssignBlock(self, node, frame):
self.blockvisit(node.body, block_frame)
self.newline(node)
self.visit(node.target, frame)
- self.write(' = concat(%s)' % block_frame.buffer)
+ self.write(' = (Markup if context.eval_ctx.autoescape '
+ 'else identity)(concat(%s))' % block_frame.buffer)
self.pop_assign_tracking(frame)
self.leave_frame(block_frame)
diff --git a/tests/test_core_tags.py b/tests/test_core_tags.py
index 7d49d8a9f..0a865f53e 100644
--- a/tests/test_core_tags.py
+++ b/tests/test_core_tags.py
@@ -348,3 +348,9 @@ def test_block(self, env_trim):
tmpl = env_trim.from_string('{% set foo %}42{% endset %}{{ foo }}')
assert tmpl.render() == '42'
assert tmpl.module.foo == u'42'
+
+ def test_block_escaping(self):
+ env = Environment(autoescape=True)
+ tmpl = env.from_string('{% set foo %}{{ test }}'
+ '{% endset %}foo: {{ foo }}')
+ assert tmpl.render(test='') == 'foo: <unsafe>'