Skip to content

Commit

Permalink
Dev Updated Twig to v1.44.2
Browse files Browse the repository at this point in the history
  • Loading branch information
c-schmitz committed Apr 23, 2021
1 parent 609e661 commit f9e8676
Show file tree
Hide file tree
Showing 32 changed files with 161 additions and 81 deletions.
10 changes: 5 additions & 5 deletions application/third_party/Twig/Environment.php
Expand Up @@ -35,17 +35,17 @@
use Twig\TokenParser\TokenParserInterface;

/**
* Stores the Twig configuration.
* Stores the Twig configuration and renders templates.
*
* @author Fabien Potencier <fabien@symfony.com>
*/
class Environment
{
const VERSION = '1.42.4';
const VERSION_ID = 14204;
const VERSION = '1.44.2';
const VERSION_ID = 14402;
const MAJOR_VERSION = 1;
const MINOR_VERSION = 42;
const RELEASE_VERSION = 4;
const MINOR_VERSION = 44;
const RELEASE_VERSION = 2;
const EXTRA_VERSION = '';

protected $charset;
Expand Down
26 changes: 21 additions & 5 deletions application/third_party/Twig/ExpressionParser.php
Expand Up @@ -376,7 +376,16 @@ public function parseHashExpression()
// * a string -- 'a'
// * a name, which is equivalent to a string -- a
// * an expression, which must be enclosed in parentheses -- (1 + 2)
if (($token = $stream->nextIf(Token::STRING_TYPE)) || ($token = $stream->nextIf(Token::NAME_TYPE)) || $token = $stream->nextIf(Token::NUMBER_TYPE)) {
if ($token = $stream->nextIf(Token::NAME_TYPE)) {
$key = new ConstantExpression($token->getValue(), $token->getLine());

// {a} is a shortcut for {a:a}
if ($stream->test(Token::PUNCTUATION_TYPE, [',', '}'])) {
$value = new NameExpression($key->getAttribute('value'), $key->getTemplateLine());
$node->addElement($value, $key);
continue;
}
} elseif (($token = $stream->nextIf(Token::STRING_TYPE)) || $token = $stream->nextIf(Token::NUMBER_TYPE)) {
$key = new ConstantExpression($token->getValue(), $token->getLine());
} elseif ($stream->test(Token::PUNCTUATION_TYPE, '(')) {
$key = $this->parseExpression();
Expand Down Expand Up @@ -598,6 +607,11 @@ public function parseArguments($namedArguments = false, $definition = false, $al
while (!$stream->test(Token::PUNCTUATION_TYPE, ')')) {
if (!empty($args)) {
$stream->expect(Token::PUNCTUATION_TYPE, ',', 'Arguments must be separated by a comma');

// if the comma above was a trailing comma, early exit the argument parse loop
if ($stream->test(Token::PUNCTUATION_TYPE, ')')) {
break;
}
}

if ($definition) {
Expand Down Expand Up @@ -657,7 +671,7 @@ public function parseAssignmentExpression()
$stream->expect(Token::NAME_TYPE, null, 'Only variables can be assigned to');
}
$value = $token->getValue();
if (\in_array(strtolower($value), ['true', 'false', 'none', 'null'])) {
if (\in_array(strtr($value, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'), ['true', 'false', 'none', 'null'])) {
throw new SyntaxError(sprintf('You cannot assign a value to "%s".', $value), $token->getLine(), $stream->getSourceContext());
}
$targets[] = new AssignNameExpression($value, $token->getLine());
Expand Down Expand Up @@ -697,6 +711,8 @@ private function parseTestExpression(\Twig_NodeInterface $node)
$arguments = null;
if ($stream->test(Token::PUNCTUATION_TYPE, '(')) {
$arguments = $this->parseArguments(true);
} elseif ($test->hasOneMandatoryArgument()) {
$arguments = new Node([0 => $this->parsePrimaryExpression()]);
}

return new $class($node, $name, $arguments, $this->parser->getCurrentToken()->getLine());
Expand Down Expand Up @@ -740,7 +756,7 @@ private function getTestNodeClass($test)
$message .= sprintf('. Use "%s" instead', $test->getAlternative());
}
$src = $stream->getSourceContext();
$message .= sprintf(' in %s at line %d.', $src->getPath() ? $src->getPath() : $src->getName(), $stream->getCurrent()->getLine());
$message .= sprintf(' in %s at line %d.', $src->getPath() ?: $src->getName(), $stream->getCurrent()->getLine());

@trigger_error($message, E_USER_DEPRECATED);
}
Expand Down Expand Up @@ -770,7 +786,7 @@ protected function getFunctionNodeClass($name, $line)
$message .= sprintf('. Use "%s" instead', $function->getAlternative());
}
$src = $this->parser->getStream()->getSourceContext();
$message .= sprintf(' in %s at line %d.', $src->getPath() ? $src->getPath() : $src->getName(), $line);
$message .= sprintf(' in %s at line %d.', $src->getPath() ?: $src->getName(), $line);

@trigger_error($message, E_USER_DEPRECATED);
}
Expand Down Expand Up @@ -800,7 +816,7 @@ protected function getFilterNodeClass($name, $line)
$message .= sprintf('. Use "%s" instead', $filter->getAlternative());
}
$src = $this->parser->getStream()->getSourceContext();
$message .= sprintf(' in %s at line %d.', $src->getPath() ? $src->getPath() : $src->getName(), $line);
$message .= sprintf(' in %s at line %d.', $src->getPath() ?: $src->getName(), $line);

@trigger_error($message, E_USER_DEPRECATED);
}
Expand Down
Expand Up @@ -65,7 +65,7 @@ public function getGlobals()
*/
public function getName()
{
return \get_class($this);
return static::class;
}
}

Expand Down
74 changes: 53 additions & 21 deletions application/third_party/Twig/Extension/CoreExtension.php
Expand Up @@ -194,9 +194,9 @@ public function getFilters()
new TwigFilter('sort', 'twig_sort_filter'),
new TwigFilter('merge', 'twig_array_merge'),
new TwigFilter('batch', 'twig_array_batch'),
new TwigFilter('filter', 'twig_array_filter'),
new TwigFilter('map', 'twig_array_map'),
new TwigFilter('reduce', 'twig_array_reduce'),
new TwigFilter('filter', 'twig_array_filter', ['needs_environment' => true]),
new TwigFilter('map', 'twig_array_map', ['needs_environment' => true]),
new TwigFilter('reduce', 'twig_array_reduce', ['needs_environment' => true]),

// string/array filters
new TwigFilter('reverse', 'twig_reverse_filter', ['needs_environment' => true]),
Expand Down Expand Up @@ -244,11 +244,11 @@ public function getTests()
new TwigTest('odd', null, ['node_class' => '\Twig\Node\Expression\Test\OddTest']),
new TwigTest('defined', null, ['node_class' => '\Twig\Node\Expression\Test\DefinedTest']),
new TwigTest('sameas', null, ['node_class' => '\Twig\Node\Expression\Test\SameasTest', 'deprecated' => '1.21', 'alternative' => 'same as']),
new TwigTest('same as', null, ['node_class' => '\Twig\Node\Expression\Test\SameasTest']),
new TwigTest('same as', null, ['node_class' => '\Twig\Node\Expression\Test\SameasTest', 'one_mandatory_argument' => true]),
new TwigTest('none', null, ['node_class' => '\Twig\Node\Expression\Test\NullTest']),
new TwigTest('null', null, ['node_class' => '\Twig\Node\Expression\Test\NullTest']),
new TwigTest('divisibleby', null, ['node_class' => '\Twig\Node\Expression\Test\DivisiblebyTest', 'deprecated' => '1.21', 'alternative' => 'divisible by']),
new TwigTest('divisible by', null, ['node_class' => '\Twig\Node\Expression\Test\DivisiblebyTest']),
new TwigTest('divisible by', null, ['node_class' => '\Twig\Node\Expression\Test\DivisiblebyTest', 'one_mandatory_argument' => true]),
new TwigTest('constant', null, ['node_class' => '\Twig\Node\Expression\Test\ConstantTest']),
new TwigTest('empty', 'twig_test_empty'),
new TwigTest('iterable', 'twig_test_iterable'),
Expand Down Expand Up @@ -313,6 +313,8 @@ class_alias('Twig\Extension\CoreExtension', 'Twig_Extension_Core');
use Twig\Markup;
use Twig\Node\Expression\ConstantExpression;
use Twig\Node\Node;
use Twig\Template;
use Twig\TemplateWrapper;

/**
* Cycles over a value.
Expand Down Expand Up @@ -459,7 +461,7 @@ function twig_date_modify_filter(Environment $env, $date, $modifier)
* @param \DateTime|\DateTimeInterface|string|null $date A date
* @param \DateTimeZone|string|false|null $timezone The target timezone, null to use the default, false to leave unchanged
*
* @return \DateTime
* @return \DateTimeInterface
*/
function twig_date_converter(Environment $env, $date = null, $timezone = null)
{
Expand Down Expand Up @@ -539,15 +541,15 @@ function twig_replace_filter($str, $from, $to = null)
*/
function twig_round($value, $precision = 0, $method = 'common')
{
if ('common' == $method) {
if ('common' === $method) {
return round($value, $precision);
}

if ('ceil' != $method && 'floor' != $method) {
if ('ceil' !== $method && 'floor' !== $method) {
throw new RuntimeError('The round filter only supports the "common", "ceil", and "floor" methods.');
}

return $method($value * pow(10, $precision)) / pow(10, $precision);
return $method($value * 10 ** $precision) / 10 ** $precision;
}

/**
Expand Down Expand Up @@ -1214,7 +1216,7 @@ function _twig_escape_js_callback($matches)

/*
* A few characters have short escape sequences in JSON and JavaScript.
* Escape sequences supported only by JavaScript, not JSON, are ommitted.
* Escape sequences supported only by JavaScript, not JSON, are omitted.
* \" is also supported but omitted, because the resulting string is not HTML safe.
*/
static $shortMap = [
Expand All @@ -1231,15 +1233,18 @@ function _twig_escape_js_callback($matches)
return $shortMap[$char];
}

// \uHHHH
$char = twig_convert_encoding($char, 'UTF-16BE', 'UTF-8');
$char = strtoupper(bin2hex($char));

if (4 >= \strlen($char)) {
return sprintf('\u%04s', $char);
$codepoint = mb_ord($char);
if (0x10000 > $codepoint) {
return sprintf('\u%04X', $codepoint);
}

return sprintf('\u%04s\u%04s', substr($char, 0, -4), substr($char, -4));
// Split characters outside the BMP into surrogate pairs
// https://tools.ietf.org/html/rfc2781.html#section-2.1
$u = $codepoint - 0x10000;
$high = 0xD800 | ($u >> 10);
$low = 0xDC00 | ($u & 0x3FF);

return sprintf('\u%04X\u%04X', $high, $low);
}

function _twig_escape_css_callback($matches)
Expand Down Expand Up @@ -1504,7 +1509,7 @@ function twig_to_array($seq, $preserveKeys = true)
function twig_test_empty($value)
{
if ($value instanceof \Countable) {
return 0 == \count($value);
return 0 === \count($value);
}

if ($value instanceof \Traversable) {
Expand Down Expand Up @@ -1560,6 +1565,13 @@ function twig_include(Environment $env, $context, $template, $variables = [], $w
if (!$alreadySandboxed = $sandbox->isSandboxed()) {
$sandbox->enableSandbox();
}

foreach ((\is_array($template) ? $template : [$template]) as $name) {
// if a Template instance is passed, it might have been instantiated outside of a sandbox, check security
if ($name instanceof TemplateWrapper || $name instanceof Template) {
$name->unwrap()->checkSecurity();
}
}
}

$loaded = null;
Expand Down Expand Up @@ -1693,8 +1705,16 @@ function twig_array_batch($items, $size, $fill = null, $preserveKeys = true)
return $result;
}

function twig_array_filter($array, $arrow)
function twig_array_filter(Environment $env, $array, $arrow)
{
if (!twig_test_iterable($array)) {
throw new RuntimeError(sprintf('The "filter" filter expects an array or "Traversable", got "%s".', \is_object($array) ? \get_class($array) : \gettype($array)));
}

if (!$arrow instanceof Closure && $env->hasExtension('\Twig\Extension\SandboxExtension') && $env->getExtension('\Twig\Extension\SandboxExtension')->isSandboxed()) {
throw new RuntimeError('The callable passed to "filter" filter must be a Closure in sandbox mode.');
}

if (\is_array($array)) {
if (\PHP_VERSION_ID >= 50600) {
return array_filter($array, $arrow, \ARRAY_FILTER_USE_BOTH);
Expand All @@ -1707,8 +1727,12 @@ function twig_array_filter($array, $arrow)
return new \CallbackFilterIterator(new \IteratorIterator($array), $arrow);
}

function twig_array_map($array, $arrow)
function twig_array_map(Environment $env, $array, $arrow)
{
if (!$arrow instanceof Closure && $env->hasExtension('\Twig\Extension\SandboxExtension') && $env->getExtension('\Twig\Extension\SandboxExtension')->isSandboxed()) {
throw new RuntimeError('The callable passed to the "map" filter must be a Closure in sandbox mode.');
}

$r = [];
foreach ($array as $k => $v) {
$r[$k] = $arrow($v, $k);
Expand All @@ -1717,9 +1741,17 @@ function twig_array_map($array, $arrow)
return $r;
}

function twig_array_reduce($array, $arrow, $initial = null)
function twig_array_reduce(Environment $env, $array, $arrow, $initial = null)
{
if (!$arrow instanceof Closure && $env->hasExtension('\Twig\Extension\SandboxExtension') && $env->getExtension('\Twig\Extension\SandboxExtension')->isSandboxed()) {
throw new RuntimeError('The callable passed to the "reduce" filter must be a Closure in sandbox mode.');
}

if (!\is_array($array)) {
if (!$array instanceof \Traversable) {
throw new RuntimeError(sprintf('The "reduce" filter only works with arrays or "Traversable", got "%s" as first argument.', \gettype($array)));
}

$array = iterator_to_array($array);
}

Expand Down
Expand Up @@ -41,7 +41,7 @@ public function leave(Profile $profile)

public function getNodeVisitors()
{
return [new ProfilerNodeVisitor(\get_class($this))];
return [new ProfilerNodeVisitor(static::class)];
}

public function getName()
Expand Down
14 changes: 9 additions & 5 deletions application/third_party/Twig/Lexer.php
Expand Up @@ -117,7 +117,7 @@ public function __construct(Environment $env, array $options = [])
// #}
'lex_comment' => '{
(?:'.
preg_quote($this->options['whitespace_trim']).preg_quote($this->options['tag_comment'][1], '#').'\s*\n?'. // -#}\s*\n?
preg_quote($this->options['whitespace_trim'].$this->options['tag_comment'][1], '#').'\s*\n?'. // -#}\s*\n?
'|'.
preg_quote($this->options['whitespace_line_trim'].$this->options['tag_comment'][1], '#').'['.$this->options['whitespace_line_chars'].']*'. // ~#}[ \t\0\x0B]*
'|'.
Expand Down Expand Up @@ -499,11 +499,15 @@ protected function getOperatorRegex()
$regex = [];
foreach ($operators as $operator => $length) {
// an operator that ends with a character must be followed by
// a whitespace or a parenthesis
// a whitespace, a parenthesis, an opening map [ or sequence {
$r = preg_quote($operator, '/');
if (ctype_alpha($operator[$length - 1])) {
$r = preg_quote($operator, '/').'(?=[\s()])';
} else {
$r = preg_quote($operator, '/');
$r .= '(?=[\s()\[{])';
}

// an operator that begins with a character must not have a dot or pipe before
if (ctype_alpha($operator[0])) {
$r = '(?<![\.\|])'.$r;
}

// an operator with a space can be any amount of whitespaces
Expand Down
2 changes: 1 addition & 1 deletion application/third_party/Twig/Loader/ArrayLoader.php
Expand Up @@ -53,7 +53,7 @@ public function setTemplate($name, $template)

public function getSource($name)
{
@trigger_error(sprintf('Calling "getSource" on "%s" is deprecated since 1.27. Use getSourceContext() instead.', \get_class($this)), E_USER_DEPRECATED);
@trigger_error(sprintf('Calling "getSource" on "%s" is deprecated since 1.27. Use getSourceContext() instead.', static::class), E_USER_DEPRECATED);

$name = (string) $name;
if (!isset($this->templates[$name])) {
Expand Down
2 changes: 1 addition & 1 deletion application/third_party/Twig/Loader/ChainLoader.php
Expand Up @@ -52,7 +52,7 @@ public function getLoaders()

public function getSource($name)
{
@trigger_error(sprintf('Calling "getSource" on "%s" is deprecated since 1.27. Use getSourceContext() instead.', \get_class($this)), E_USER_DEPRECATED);
@trigger_error(sprintf('Calling "getSource" on "%s" is deprecated since 1.27. Use getSourceContext() instead.', static::class), E_USER_DEPRECATED);

$exceptions = [];
foreach ($this->loaders as $loader) {
Expand Down
4 changes: 2 additions & 2 deletions application/third_party/Twig/Loader/FilesystemLoader.php
Expand Up @@ -138,7 +138,7 @@ public function prependPath($path, $namespace = self::MAIN_NAMESPACE)

public function getSource($name)
{
@trigger_error(sprintf('Calling "getSource" on "%s" is deprecated since 1.27. Use getSourceContext() instead.', \get_class($this)), E_USER_DEPRECATED);
@trigger_error(sprintf('Calling "getSource" on "%s" is deprecated since 1.27. Use getSourceContext() instead.', static::class), E_USER_DEPRECATED);

if (null === ($path = $this->findTemplate($name)) || false === $path) {
return '';
Expand Down Expand Up @@ -180,7 +180,7 @@ public function exists($name)
try {
return null !== ($path = $this->findTemplate($name, false)) && false !== $path;
} catch (LoaderError $e) {
@trigger_error(sprintf('In %s::findTemplate(), you must accept a second argument that when set to "false" returns "false" instead of throwing an exception. Not supporting this argument is deprecated since version 1.27.', \get_class($this)), E_USER_DEPRECATED);
@trigger_error(sprintf('In %s::findTemplate(), you must accept a second argument that when set to "false" returns "false" instead of throwing an exception. Not supporting this argument is deprecated since version 1.27.', static::class), E_USER_DEPRECATED);

return false;
}
Expand Down
13 changes: 9 additions & 4 deletions application/third_party/Twig/Node/CheckSecurityNode.php
Expand Up @@ -45,10 +45,13 @@ public function compile(Compiler $compiler)
}

$compiler
->write("\$this->sandbox = \$this->env->getExtension('\Twig\Extension\SandboxExtension');\n")
->write('$tags = ')->repr(array_filter($tags))->raw(";\n")
->write('$filters = ')->repr(array_filter($filters))->raw(";\n")
->write('$functions = ')->repr(array_filter($functions))->raw(";\n\n")
->write("\n")
->write("public function checkSecurity()\n")
->write("{\n")
->indent()
->write('static $tags = ')->repr(array_filter($tags))->raw(";\n")
->write('static $filters = ')->repr(array_filter($filters))->raw(";\n")
->write('static $functions = ')->repr(array_filter($functions))->raw(";\n\n")
->write("try {\n")
->indent()
->write("\$this->sandbox->checkSecurity(\n")
Expand Down Expand Up @@ -78,6 +81,8 @@ public function compile(Compiler $compiler)
->write("throw \$e;\n")
->outdent()
->write("}\n\n")
->outdent()
->write("}\n")
;
}
}
Expand Down
2 changes: 1 addition & 1 deletion application/third_party/Twig/Node/EmbedNode.php
Expand Up @@ -23,7 +23,7 @@
class EmbedNode extends IncludeNode
{
// we don't inject the module to avoid node visitors to traverse it twice (as it will be already visited in the main module)
public function __construct($name, $index, AbstractExpression $variables = null, $only = false, $ignoreMissing = false, $lineno, $tag = null)
public function __construct($name, $index, ?AbstractExpression $variables, $only, $ignoreMissing, $lineno, $tag = null)
{
parent::__construct(new ConstantExpression('not_used', $lineno), $variables, $only, $ignoreMissing, $lineno, $tag);

Expand Down
Expand Up @@ -25,7 +25,7 @@ class BlockReferenceExpression extends AbstractExpression
/**
* @param Node|null $template
*/
public function __construct(\Twig_NodeInterface $name, $template = null, $lineno, $tag = null)
public function __construct(\Twig_NodeInterface $name, $template, $lineno, $tag = null)
{
if (\is_bool($template)) {
@trigger_error(sprintf('The %s method "$asString" argument is deprecated since version 1.28 and will be removed in 2.0.', __METHOD__), E_USER_DEPRECATED);
Expand Down

0 comments on commit f9e8676

Please sign in to comment.