mirror of
https://github.com/twigphp/Twig.git
synced 2026-09-15 11:56:50 +00:00
A proposed fix for the {% embed %} error line number bug from fabpot/Twig#958
I've spent some time staring at the order of invocation when {% embed %} is
involved, the state of the call stack, and the compiler output. This commit
changes guessTemplateInfo based on the following rationale.
Given a call stack looking like this:
#0 Twig_Error->guessTemplateInfo() called at [/Users/h2s/src/Twig/lib/Twig/Error.php:71]
#1 Twig_Error->__construct() called at [/Users/h2s/src/Twig/lib/Twig/Template.php:317]
#2 Twig_Template->getContext() called at [/Users/h2s/src/Twig/lib/Twig/Environment.php(320) : eval()'d code:74]
#3 __TwigTemplate_aee336d6e9d8c7d63204036df7919fc1_2059451906->block_c1()
#4 call_user_func() called at [/Users/h2s/src/Twig/lib/Twig/Template.php:133]
#5 Twig_Template->displayBlock() called at [/Users/h2s/src/Twig/lib/Twig/Environment.php(320) : eval()'d code:20]
#6 __TwigTemplate_c5df0c3d9cd7a9fd242778fcd97bc691->doDisplay() called at [/Users/h2s/src/Twig/lib/Twig/Template.php:264]
#7 Twig_Template->displayWithErrorHandling() called at [/Users/h2s/src/Twig/lib/Twig/Template.php:238]
#8 Twig_Template->display() called at [/Users/h2s/src/Twig/lib/Twig/Environment.php(320) : eval()'d code:66]
#9 __TwigTemplate_aee336d6e9d8c7d63204036df7919fc1_2059451906->doDisplay() called at [/Users/h2s/src/Twig/lib/Twig/Template.php:264]
#10 Twig_Template->displayWithErrorHandling() called at [/Users/h2s/src/Twig/lib/Twig/Template.php:238]
#11 Twig_Template->display() called at [/Users/h2s/src/Twig/lib/Twig/Environment.php(320) : eval()'d code:22]
#12 __TwigTemplate_aee336d6e9d8c7d63204036df7919fc1->doDisplay() called at [/Users/h2s/src/Twig/lib/Twig/Template.php:264]
#13 Twig_Template->displayWithErrorHandling() called at [/Users/h2s/src/Twig/lib/Twig/Template.php:238]
#14 Twig_Template->display() called at [/Users/h2s/src/Twig/lib/Twig/Template.php:249]
#15 Twig_Template->render() called at [/Users/h2s/src/Twig/lib/Twig/Environment.php:288]
The fact that __TwigTemplate_aee336d6e9d8c7d63204036df7919fc1_2059451906 is
higher than __TwigTemplate_aee336d6e9d8c7d63204036df7919fc1 means that the error
occurred in the embedded block template. However, both of these templates return
the same value when $trace['object']->getTemplateName() is called. This means
that the "if" statement modified by this commit was returning true, allowing
$this->template to be overwritten incorrectly with the instance of
__TwigTemplate_aee336d6e9d8c7d63204036df7919fc1 despite already containing the
correct __TwigTemplate_aee336d6e9d8c7d63204036df7919fc1_2059451906 instance from
higher in the stack.
So my fix for this bug is to reject any candiate templates - even if their
templateName is a match - if their class name is a strict prefix of an
already-selected template from higher up in the call stack.
This commit is contained in:
+7
-1
@@ -186,6 +186,7 @@ class Twig_Error extends Exception
|
||||
protected function guessTemplateInfo()
|
||||
{
|
||||
$template = null;
|
||||
$templateClass = null;
|
||||
|
||||
if (version_compare(phpversion(), '5.3.6', '>=')) {
|
||||
$backtrace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS | DEBUG_BACKTRACE_PROVIDE_OBJECT);
|
||||
@@ -195,8 +196,13 @@ class Twig_Error extends Exception
|
||||
|
||||
foreach ($backtrace as $trace) {
|
||||
if (isset($trace['object']) && $trace['object'] instanceof Twig_Template && 'Twig_Template' !== get_class($trace['object'])) {
|
||||
if (null === $this->filename || $this->filename == $trace['object']->getTemplateName()) {
|
||||
$currentClass = get_class($trace['object']);
|
||||
$classNameIsPrefix = strpos($templateClass, $currentClass) === 0;
|
||||
$classNameIsShorter = strlen($currentClass) < strlen($templateClass);
|
||||
$isEmbedContainer = $classNameIsPrefix && $classNameIsShorter;
|
||||
if (null === $this->filename || ($this->filename == $trace['object']->getTemplateName() && !$isEmbedContainer)) {
|
||||
$template = $trace['object'];
|
||||
$templateClass = get_class($trace['object']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user