mirror of
https://github.com/twigphp/Twig.git
synced 2026-09-13 02:46:29 +00:00
Remove deprecated code
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
# 4.0.0 (2026-XX-XX)
|
||||
|
||||
* Add the `isAlwaysAllowedInSandbox()` method to `Twig\TwigCallableInterface` and `Twig\TokenParser\TokenParserInterface`
|
||||
* Remove the `Twig\Sandbox\SourcePolicyInterface` interface and the corresponding argument of `Twig\Extension\SandboxExtension::__construct()`
|
||||
* Enforce the `parent`, `block`, and `attribute` functions against the sandbox `allowedFunctions` allow-list
|
||||
|
||||
|
||||
@@ -46,26 +46,9 @@ allowed and will generate a ``\Twig\Sandbox\SecurityError`` exception.
|
||||
Note that native array-like classes (like ``ArrayObject``) are always
|
||||
allowed, you don't need to configure them.
|
||||
|
||||
.. caution::
|
||||
|
||||
The ``extends`` and ``use`` tags, as well as the ``parent``, ``block``, and
|
||||
``attribute`` functions are always allowed in a sandboxed template. That
|
||||
behavior will change in 4.0 where they will need to be explicitly allowed
|
||||
like any other tag or function. To opt-in to the 4.0 behavior now (so they
|
||||
need to be allow-listed or get rejected), enable strict mode on the
|
||||
security policy::
|
||||
|
||||
$policy->setStrict(true);
|
||||
|
||||
Marking Filters, Functions, and Tags as Always Allowed
|
||||
------------------------------------------------------
|
||||
|
||||
.. versionadded:: 3.28
|
||||
|
||||
The ``always_allowed_in_sandbox`` option for filters and functions, and
|
||||
the ``isAlwaysAllowedInSandbox()`` method for token parsers, were added in
|
||||
Twig 3.28.
|
||||
|
||||
Some filters, functions, and tags are inherently safe and should always be
|
||||
usable in sandboxed templates without forcing every policy to allow-list them.
|
||||
Mark such callables by setting the ``always_allowed_in_sandbox`` option to
|
||||
|
||||
@@ -28,8 +28,6 @@ use Twig\Node\Expression\Variable\ContextVariable;
|
||||
use Twig\Node\ModuleNode;
|
||||
use Twig\Node\Node;
|
||||
use Twig\Node\Nodes;
|
||||
use Twig\TokenParser\TokenParserInterface;
|
||||
use Twig\TwigCallableInterface;
|
||||
use Twig\Util\CallableParameters;
|
||||
|
||||
/**
|
||||
@@ -211,7 +209,7 @@ final class SandboxNodeVisitor implements NodeVisitorInterface
|
||||
return false;
|
||||
}
|
||||
|
||||
return self::isAlwaysAllowedInSandbox($parser);
|
||||
return $parser->isAlwaysAllowedInSandbox();
|
||||
}
|
||||
|
||||
private function isFilterAlwaysAllowedInSandbox(Environment $env, FilterExpression $node): bool
|
||||
@@ -222,7 +220,7 @@ final class SandboxNodeVisitor implements NodeVisitorInterface
|
||||
return false;
|
||||
}
|
||||
|
||||
return self::isAlwaysAllowedInSandbox($filter);
|
||||
return $filter->isAlwaysAllowedInSandbox();
|
||||
}
|
||||
|
||||
private function isFunctionAlwaysAllowedInSandbox(Environment $env, FunctionExpression $node): bool
|
||||
@@ -233,7 +231,7 @@ final class SandboxNodeVisitor implements NodeVisitorInterface
|
||||
return false;
|
||||
}
|
||||
|
||||
return self::isAlwaysAllowedInSandbox($function);
|
||||
return $function->isAlwaysAllowedInSandbox();
|
||||
}
|
||||
|
||||
private function isSandboxedFunctionAlwaysAllowedInSandbox(Environment $env, Node $node, string $name): bool
|
||||
@@ -244,7 +242,7 @@ final class SandboxNodeVisitor implements NodeVisitorInterface
|
||||
return false;
|
||||
}
|
||||
|
||||
return self::isAlwaysAllowedInSandbox($function);
|
||||
return $function->isAlwaysAllowedInSandbox();
|
||||
}
|
||||
|
||||
private function isFunctionNameAlwaysAllowedInSandbox(Environment $env, string $name): bool
|
||||
@@ -253,22 +251,7 @@ final class SandboxNodeVisitor implements NodeVisitorInterface
|
||||
return false;
|
||||
}
|
||||
|
||||
return self::isAlwaysAllowedInSandbox($function);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param TwigCallableInterface|TokenParserInterface $subject
|
||||
*/
|
||||
private static function isAlwaysAllowedInSandbox($subject): bool
|
||||
{
|
||||
if (method_exists($subject, 'isAlwaysAllowedInSandbox')) {
|
||||
return $subject->isAlwaysAllowedInSandbox();
|
||||
}
|
||||
|
||||
$interface = $subject instanceof TokenParserInterface ? TokenParserInterface::class : TwigCallableInterface::class;
|
||||
trigger_deprecation('twig/twig', '3.28', 'Not implementing the "isAlwaysAllowedInSandbox()" method in "%s" is deprecated. This method will be part of the "%s" interface in 4.0.', $subject::class, $interface);
|
||||
|
||||
return false;
|
||||
return $function->isAlwaysAllowedInSandbox();
|
||||
}
|
||||
|
||||
public function getPriority(): int
|
||||
|
||||
@@ -20,8 +20,6 @@ use Twig\Token;
|
||||
* Interface implemented by token parsers.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* @method bool isAlwaysAllowedInSandbox() Whether the tag is always allowed in sandbox mode, even when not explicitly allow-listed. Not implementing this method is deprecated since Twig 3.28, it will be required in 4.0.
|
||||
*/
|
||||
interface TokenParserInterface
|
||||
{
|
||||
@@ -41,4 +39,9 @@ interface TokenParserInterface
|
||||
* Gets the tag name associated with this token parser.
|
||||
*/
|
||||
public function getTag(): string;
|
||||
|
||||
/**
|
||||
* Whether the tag is always allowed in sandbox mode, even when not explicitly allow-listed.
|
||||
*/
|
||||
public function isAlwaysAllowedInSandbox(): bool;
|
||||
}
|
||||
|
||||
@@ -13,9 +13,6 @@ namespace Twig;
|
||||
|
||||
/**
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* @method bool needsIsSandboxed() Whether the callable needs the current sandbox state passed as an argument. Not implementing this method is deprecated since Twig 3.25, it will be required in 4.0.
|
||||
* @method bool isAlwaysAllowedInSandbox() Whether the callable is always allowed in sandbox mode, even when not explicitly allow-listed. Not implementing this method is deprecated since Twig 3.28, it will be required in 4.0.
|
||||
*/
|
||||
interface TwigCallableInterface extends \Stringable
|
||||
{
|
||||
@@ -40,6 +37,8 @@ interface TwigCallableInterface extends \Stringable
|
||||
|
||||
public function needsIsSandboxed(): bool;
|
||||
|
||||
public function isAlwaysAllowedInSandbox(): bool;
|
||||
|
||||
public function withDynamicArguments(string $name, string $dynamicName, array $arguments): self;
|
||||
|
||||
public function getArguments(): array;
|
||||
|
||||
@@ -21,7 +21,6 @@ namespace Twig\Tests\Extension;
|
||||
*/
|
||||
|
||||
use PHPUnit\Framework\Attributes\DataProvider;
|
||||
use PHPUnit\Framework\Attributes\IgnoreDeprecations;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Twig\Environment;
|
||||
use Twig\Error\RuntimeError;
|
||||
@@ -44,7 +43,6 @@ use Twig\Sandbox\SecurityPolicy;
|
||||
use Twig\Source;
|
||||
use Twig\Token;
|
||||
use Twig\TokenParser\AbstractTokenParser;
|
||||
use Twig\TokenParser\TokenParserInterface;
|
||||
use Twig\TwigFilter;
|
||||
use Twig\TwigFunction;
|
||||
use Twig\TwigTest;
|
||||
@@ -1550,18 +1548,6 @@ EOF
|
||||
$this->expectExceptionMessage('Calling "__tostring" method on a "'.FooObject::class.'" object is not allowed');
|
||||
$twig->load('index')->render(['obj' => new FooObject()]);
|
||||
}
|
||||
|
||||
#[IgnoreDeprecations]
|
||||
public function testCustomTokenParserWithoutIsAlwaysAllowedInSandboxTriggersDeprecation()
|
||||
{
|
||||
$twig = $this->getEnvironment(true, [], ['index' => '{% legacy_tag %}'], tags: ['legacy_tag']);
|
||||
$twig->addTokenParser(new LegacyTokenParserWithoutIsAlwaysAllowedInSandbox());
|
||||
|
||||
$this->expectUserDeprecationMessage(\sprintf('Since twig/twig 3.28: Not implementing the "isAlwaysAllowedInSandbox()" method in "%s" is deprecated. This method will be part of the "Twig\TokenParser\TokenParserInterface" interface in 4.0.', LegacyTokenParserWithoutIsAlwaysAllowedInSandbox::class));
|
||||
|
||||
// tag is allow-listed, so the render itself succeeds; the deprecation fires from the sandbox visitor while compiling
|
||||
$this->assertSame('', $twig->load('index')->render([]));
|
||||
}
|
||||
}
|
||||
|
||||
class ParentClass
|
||||
@@ -1744,25 +1730,3 @@ class GatedSandboxTokenParser extends AbstractTokenParser
|
||||
return 'gated_tag';
|
||||
}
|
||||
}
|
||||
|
||||
class LegacyTokenParserWithoutIsAlwaysAllowedInSandbox implements TokenParserInterface
|
||||
{
|
||||
private Parser $parser;
|
||||
|
||||
public function setParser(Parser $parser): void
|
||||
{
|
||||
$this->parser = $parser;
|
||||
}
|
||||
|
||||
public function parse(Token $token): Node
|
||||
{
|
||||
$this->parser->getStream()->expect(Token::BLOCK_END_TYPE);
|
||||
|
||||
return new TextNode('', $token->getLine());
|
||||
}
|
||||
|
||||
public function getTag(): string
|
||||
{
|
||||
return 'legacy_tag';
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user