mirror of
https://github.com/twigphp/Twig.git
synced 2026-09-15 20:06:31 +00:00
Prevent importing or calling reserved macro names
This also fixes the logic detecting reserved macro names to account for the fact that they are compiled prefixed with get() since a very long time and the logic preventing conflicts was broken.
This commit is contained in:
committed by
Fabien Potencier
parent
cfb0593028
commit
7b6c0e971f
@@ -387,7 +387,13 @@ class Twig_ExpressionParser
|
||||
throw new Twig_Error_Syntax(sprintf('Dynamic macro names are not supported (called on "%s")', $node->getAttribute('name')), $token->getLine(), $this->parser->getFilename());
|
||||
}
|
||||
|
||||
$node = new Twig_Node_Expression_MethodCall($node, 'get'.$arg->getAttribute('value'), $arguments, $lineno);
|
||||
$name = $arg->getAttribute('value');
|
||||
|
||||
if ($this->parser->isReservedMacroName($name)) {
|
||||
throw new Twig_Error_Syntax(sprintf('"%s" cannot be called as macro as it is a reserved keyword', $name), $token->getLine(), $this->parser->getFilename());
|
||||
}
|
||||
|
||||
$node = new Twig_Node_Expression_MethodCall($node, 'get'.$name, $arguments, $lineno);
|
||||
$node->setAttribute('safe', true);
|
||||
|
||||
return $node;
|
||||
|
||||
+18
-9
@@ -254,21 +254,30 @@ class Twig_Parser implements Twig_ParserInterface
|
||||
|
||||
public function setMacro($name, Twig_Node_Macro $node)
|
||||
{
|
||||
if (null === $this->reservedMacroNames) {
|
||||
$this->reservedMacroNames = array();
|
||||
$r = new ReflectionClass($this->env->getBaseTemplateClass());
|
||||
foreach ($r->getMethods() as $method) {
|
||||
$this->reservedMacroNames[] = $method->getName();
|
||||
}
|
||||
}
|
||||
|
||||
if (in_array($name, $this->reservedMacroNames)) {
|
||||
if ($this->isReservedMacroName($name)) {
|
||||
throw new Twig_Error_Syntax(sprintf('"%s" cannot be used as a macro name as it is a reserved keyword', $name), $node->getLine(), $this->getFilename());
|
||||
}
|
||||
|
||||
$this->macros[$name] = $node;
|
||||
}
|
||||
|
||||
public function isReservedMacroName($name)
|
||||
{
|
||||
if (null === $this->reservedMacroNames) {
|
||||
$this->reservedMacroNames = array();
|
||||
$r = new ReflectionClass($this->env->getBaseTemplateClass());
|
||||
foreach ($r->getMethods() as $method) {
|
||||
$methodName = strtolower($method->getName());
|
||||
|
||||
if ('get' === substr($methodName, 0, 3) && isset($methodName[3])) {
|
||||
$this->reservedMacroNames[] = substr($methodName, 3);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return in_array(strtolower($name), $this->reservedMacroNames);
|
||||
}
|
||||
|
||||
public function addTrait($trait)
|
||||
{
|
||||
$this->traits[] = $trait;
|
||||
|
||||
@@ -52,6 +52,10 @@ class Twig_TokenParser_From extends Twig_TokenParser
|
||||
$node = new Twig_Node_Import($macro, new Twig_Node_Expression_AssignName($this->parser->getVarName(), $token->getLine()), $token->getLine(), $this->getTag());
|
||||
|
||||
foreach ($targets as $name => $alias) {
|
||||
if ($this->parser->isReservedMacroName($name)) {
|
||||
throw new Twig_Error_Syntax(sprintf('"%s" cannot be an imported macro as it is a reserved keyword', $name), $token->getLine(), $stream->getFilename());
|
||||
}
|
||||
|
||||
$this->parser->addImportedSymbol('function', $alias, 'get'.$name, $node->getNode('var'));
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
--TEST--
|
||||
"from" tag with reserved name
|
||||
--TEMPLATE--
|
||||
{% from 'forms.twig' import templateName %}
|
||||
--TEMPLATE(forms.twig)--
|
||||
--DATA--
|
||||
return array()
|
||||
--EXCEPTION--
|
||||
Twig_Error_Syntax: "templateName" cannot be an imported macro as it is a reserved keyword in "index.twig" at line 2
|
||||
@@ -0,0 +1,11 @@
|
||||
--TEST--
|
||||
"from" tag with reserved name
|
||||
--TEMPLATE--
|
||||
{% import 'forms.twig' as macros %}
|
||||
|
||||
{{ macros.parent() }}
|
||||
--TEMPLATE(forms.twig)--
|
||||
--DATA--
|
||||
return array()
|
||||
--EXCEPTION--
|
||||
Twig_Error_Syntax: "parent" cannot be called as macro as it is a reserved keyword in "index.twig" at line 4
|
||||
@@ -0,0 +1,10 @@
|
||||
--TEST--
|
||||
"macro" tag with reserved name
|
||||
--TEMPLATE--
|
||||
{% macro parent(arg1, arg2) %}
|
||||
parent
|
||||
{% endmacro %}
|
||||
--DATA--
|
||||
return array()
|
||||
--EXCEPTION--
|
||||
Twig_Error_Syntax: "parent" cannot be used as a macro name as it is a reserved keyword in "index.twig" at line 2
|
||||
@@ -16,7 +16,7 @@ class Twig_Tests_ParserTest extends PHPUnit_Framework_TestCase
|
||||
public function testSetMacroThrowsExceptionOnReservedMethods()
|
||||
{
|
||||
$parser = $this->getParser();
|
||||
$parser->setMacro('display', $this->getMock('Twig_Node_Macro', array(), array(), '', null));
|
||||
$parser->setMacro('parent', $this->getMock('Twig_Node_Macro', array(), array(), '', null));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user