diff --git a/lib/Twig/Template.php b/lib/Twig/Template.php
index 54f6b0dcd..bedc7e9ca 100644
--- a/lib/Twig/Template.php
+++ b/lib/Twig/Template.php
@@ -197,12 +197,16 @@ abstract class Twig_Template implements Twig_TemplateInterface
$block = null;
}
- if (null !== $template) {
- // avoid RCEs when sandbox is enabled
- if (!$template instanceof self) {
- throw new LogicException('A block must be a method on a Twig_Template instance.');
- }
+ // avoid RCEs when sandbox is enabled
+ if (null !== $template && !$template instanceof self) {
+ throw new LogicException('A block must be a method on a Twig_Template instance.');
+ }
+ if (!$this->hasBlock($name, $context, $blocks)) {
+ @trigger_error(sprintf('Displaying undefined block "%s" in template "%s" is deprecated since version 1.29 and will throw an exception in 2.0.', $name, $this->getTemplateName()), E_USER_DEPRECATED);
+ }
+
+ if (null !== $template) {
try {
$template->$block($context, $blocks);
} catch (Twig_Error $e) {
diff --git a/test/Twig/Tests/Fixtures/functions/recursive_block_with_inheritance.test b/test/Twig/Tests/Fixtures/functions/recursive_block_with_inheritance.test
index f39712da8..bf0556d24 100644
--- a/test/Twig/Tests/Fixtures/functions/recursive_block_with_inheritance.test
+++ b/test/Twig/Tests/Fixtures/functions/recursive_block_with_inheritance.test
@@ -12,7 +12,7 @@
{% block list %}
{% endblock %}
{% block children %}{% set currentItem = item %}{% for item in currentItem %}{{ block('item') }}{% endfor %}{% set item = currentItem %}{% endblock %}
{% block item %}{% if item is not iterable %}{{ block('label') }}{% else %}{{ block('list') }}{% endif %}{% endblock %}
-{% block label %}{{ item }}{{ block('unknown') }}{% endblock %}
+{% block label %}{{ item }}{% endblock %}
--TEMPLATE(base.twig)--
{{ block('list') }}
--DATA--
diff --git a/test/Twig/Tests/LegacyFixtures/functions/undefined_block.legacy.test b/test/Twig/Tests/LegacyFixtures/functions/undefined_block.legacy.test
new file mode 100644
index 000000000..62e24f0f4
--- /dev/null
+++ b/test/Twig/Tests/LegacyFixtures/functions/undefined_block.legacy.test
@@ -0,0 +1,12 @@
+--TEST--
+"block" function with undefined block
+--TEMPLATE--
+{% extends "base.twig" %}
+{% block foo %}{{ parent() }}{{ block('unknown') }}{{ block('bar') }}{% endblock %}
+--TEMPLATE(base.twig)--
+{% block foo %}Foo{% endblock %}
+{% block bar %}Bar{% endblock %}
+--DATA--
+return array()
+--EXPECT--
+FooBarBar
diff --git a/test/Twig/Tests/TemplateTest.php b/test/Twig/Tests/TemplateTest.php
index 610b8c6c1..821e2c7a8 100644
--- a/test/Twig/Tests/TemplateTest.php
+++ b/test/Twig/Tests/TemplateTest.php
@@ -214,15 +214,17 @@ class Twig_Tests_TemplateTest extends PHPUnit_Framework_TestCase
$this->assertNotInstanceof('Twig_Markup', $template->getAttribute($template1, 'empty'));
$this->assertSame('', $template->getAttribute($template1, 'empty'));
+ $blocks = array('name' => array($template1, 'block_name'));
+
// trigger some deprecation notice messages to check them with @expectedDeprecation
- $template->getAttribute($template, 'renderBlock', array('name', array()));
- $template->getAttribute($template, 'displayBlock', array('name', array()));
+ $template->getAttribute($template, 'renderBlock', array('name', array(), $blocks));
+ $template->getAttribute($template, 'displayBlock', array('name', array(), $blocks));
$template->getAttribute($template, 'hasBlock', array('name', array()));
$template->getAttribute($template, 'render', array(array()));
$template->getAttribute($template, 'display', array(array()));
- $template->getAttribute($template1, 'renderBlock', array('name', array()));
- $template->getAttribute($template1, 'displayBlock', array('name', array()));
+ $template->getAttribute($template1, 'renderBlock', array('name', array(), $blocks));
+ $template->getAttribute($template1, 'displayBlock', array('name', array(), $blocks));
$template->getAttribute($template1, 'hasBlock', array('name', array()));
$template->getAttribute($template1, 'render', array(array()));
$template->getAttribute($template1, 'display', array(array()));
@@ -233,6 +235,20 @@ class Twig_Tests_TemplateTest extends PHPUnit_Framework_TestCase
$this->assertFalse($template->getAttribute($template1, 'displayWithErrorHandling', array(), Twig_Template::METHOD_CALL, true));
}
+ /**
+ * @group legacy
+ * @expectedDeprecation Displaying undefined block "unknown" in template "index.twig" is deprecated since version 1.29 and will throw an exception in 2.0.
+ * @expectedDeprecation Displaying undefined block "unknown" in template "index.twig" is deprecated since version 1.29 and will throw an exception in 2.0.
+ */
+ public function testRenderBlockWithUndefinedBlock()
+ {
+ $twig = new Twig_Environment($this->getMockBuilder('Twig_TemplateTestLoaderInterface')->getMock());
+
+ $template = new Twig_TemplateTest($twig, false, 'index.twig');
+ $template->renderBlock('unknown', array());
+ $template->displayBlock('unknown', array());
+ }
+
/**
* @dataProvider getTestsDependingOnExtensionAvailability
*/
@@ -534,6 +550,10 @@ class Twig_TemplateTest extends Twig_Template
return parent::getAttribute($object, $item, $arguments, $type, $isDefinedTest, $ignoreStrictCheck);
}
}
+
+ public function block_name($context, array $blocks = array())
+ {
+ }
}
class Twig_TemplateArrayAccessObject implements ArrayAccess