mirror of
https://github.com/twigphp/Twig.git
synced 2026-09-17 21:07:18 +00:00
Fix EscapeNodeVisitor::isSafeFor()
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
# 3.16.0 (2024-XX-XX)
|
# 3.16.0 (2024-XX-XX)
|
||||||
|
|
||||||
* Deprecate not passing a `Source` instance to `TokenStream`
|
* Deprecate not passing a `Source` instance to `TokenStream`
|
||||||
|
* Deprecate returning `null` from `TwigFilter::getSafe()` and `TwigFunction::getSafe()`, return `[]` instead
|
||||||
|
|
||||||
# 3.15.0 (2024-11-17)
|
# 3.15.0 (2024-11-17)
|
||||||
|
|
||||||
|
|||||||
@@ -319,6 +319,10 @@ Functions/Filters/Tests
|
|||||||
arrow functions is deprecated as of Twig 3.15; these arguments will have a
|
arrow functions is deprecated as of Twig 3.15; these arguments will have a
|
||||||
``\Closure`` type hint in 4.0.
|
``\Closure`` type hint in 4.0.
|
||||||
|
|
||||||
|
* Returning ``null`` from ``TwigFilter::getSafe()`` and
|
||||||
|
``TwigFunction::getSafe()`` is deprecated as of Twig 3.16; return ``[]``
|
||||||
|
instead.
|
||||||
|
|
||||||
Node
|
Node
|
||||||
----
|
----
|
||||||
|
|
||||||
|
|||||||
@@ -172,7 +172,7 @@ final class EscaperNodeVisitor implements NodeVisitorInterface
|
|||||||
{
|
{
|
||||||
$safe = $this->safeAnalysis->getSafe($expression);
|
$safe = $this->safeAnalysis->getSafe($expression);
|
||||||
|
|
||||||
if (null === $safe) {
|
if (!$safe) {
|
||||||
if (null === $this->traverser) {
|
if (null === $this->traverser) {
|
||||||
$this->traverser = new NodeTraverser($env, [$this->safeAnalysis]);
|
$this->traverser = new NodeTraverser($env, [$this->safeAnalysis]);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,11 +37,14 @@ final class SafeAnalysisNodeVisitor implements NodeVisitorInterface
|
|||||||
$this->safeVars = $safeVars;
|
$this->safeVars = $safeVars;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
public function getSafe(Node $node)
|
public function getSafe(Node $node)
|
||||||
{
|
{
|
||||||
$hash = spl_object_hash($node);
|
$hash = spl_object_hash($node);
|
||||||
if (!isset($this->data[$hash])) {
|
if (!isset($this->data[$hash])) {
|
||||||
return;
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($this->data[$hash] as $bucket) {
|
foreach ($this->data[$hash] as $bucket) {
|
||||||
@@ -55,6 +58,8 @@ final class SafeAnalysisNodeVisitor implements NodeVisitorInterface
|
|||||||
|
|
||||||
return $bucket['value'];
|
return $bucket['value'];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
private function setSafe(Node $node, array $safe): void
|
private function setSafe(Node $node, array $safe): void
|
||||||
@@ -107,11 +112,14 @@ final class SafeAnalysisNodeVisitor implements NodeVisitorInterface
|
|||||||
if ($filter) {
|
if ($filter) {
|
||||||
$safe = $filter->getSafe($node->getNode('arguments'));
|
$safe = $filter->getSafe($node->getNode('arguments'));
|
||||||
if (null === $safe) {
|
if (null === $safe) {
|
||||||
|
trigger_deprecation('twig/twig', '3.16', 'The "%s::getSafe()" method should not return "null" anymore, return "[]" instead.', $filter::class);
|
||||||
|
$safe = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$safe) {
|
||||||
$safe = $this->intersectSafe($this->getSafe($node->getNode('node')), $filter->getPreservesSafety());
|
$safe = $this->intersectSafe($this->getSafe($node->getNode('node')), $filter->getPreservesSafety());
|
||||||
}
|
}
|
||||||
$this->setSafe($node, $safe);
|
$this->setSafe($node, $safe);
|
||||||
} else {
|
|
||||||
$this->setSafe($node, []);
|
|
||||||
}
|
}
|
||||||
} elseif ($node instanceof FunctionExpression) {
|
} elseif ($node instanceof FunctionExpression) {
|
||||||
// function expression is safe when the function is safe
|
// function expression is safe when the function is safe
|
||||||
@@ -123,9 +131,12 @@ final class SafeAnalysisNodeVisitor implements NodeVisitorInterface
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ($function) {
|
if ($function) {
|
||||||
$this->setSafe($node, $function->getSafe($node->getNode('arguments')));
|
$safe = $function->getSafe($node->getNode('arguments'));
|
||||||
} else {
|
if (null === $safe) {
|
||||||
$this->setSafe($node, []);
|
trigger_deprecation('twig/twig', '3.16', 'The "%s::getSafe()" method should not return "null" anymore, return "[]" instead.', $function::class);
|
||||||
|
$safe = [];
|
||||||
|
}
|
||||||
|
$this->setSafe($node, $safe);
|
||||||
}
|
}
|
||||||
} elseif ($node instanceof MethodCallExpression || $node instanceof MacroReferenceExpression) {
|
} elseif ($node instanceof MethodCallExpression || $node instanceof MacroReferenceExpression) {
|
||||||
// all macro calls are safe
|
// all macro calls are safe
|
||||||
@@ -134,19 +145,15 @@ final class SafeAnalysisNodeVisitor implements NodeVisitorInterface
|
|||||||
$name = $node->getNode('node')->getAttribute('name');
|
$name = $node->getNode('node')->getAttribute('name');
|
||||||
if (\in_array($name, $this->safeVars)) {
|
if (\in_array($name, $this->safeVars)) {
|
||||||
$this->setSafe($node, ['all']);
|
$this->setSafe($node, ['all']);
|
||||||
} else {
|
|
||||||
$this->setSafe($node, []);
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
$this->setSafe($node, []);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return $node;
|
return $node;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function intersectSafe(?array $a = null, ?array $b = null): array
|
private function intersectSafe(array $a, array $b): array
|
||||||
{
|
{
|
||||||
if (null === $a || null === $b) {
|
if (!$a || !$b) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+3
-3
@@ -54,12 +54,12 @@ final class TwigFilter extends AbstractTwigCallable
|
|||||||
return $this->options['is_safe_callback']($filterArgs);
|
return $this->options['is_safe_callback']($filterArgs);
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getPreservesSafety(): ?array
|
public function getPreservesSafety(): array
|
||||||
{
|
{
|
||||||
return $this->options['preserves_safety'];
|
return $this->options['preserves_safety'] ?? [];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getPreEscape(): ?string
|
public function getPreEscape(): ?string
|
||||||
|
|||||||
Reference in New Issue
Block a user