Deprecate the "Twig\Sandbox\SourcePolicyInterface" interface

This commit is contained in:
Fabien Potencier
2026-05-21 15:28:35 +02:00
parent af86a386bf
commit bd924d5d33
5 changed files with 41 additions and 1 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
# 3.26.1 (2026-XX-XX)
* n/a
* Deprecate the `Twig\Sandbox\SourcePolicyInterface` interface with no replacement
# 3.26.0 (2026-05-20)
+4
View File
@@ -304,6 +304,10 @@ Sandbox
deprecated as of Twig 3.12. You will need to explicitly allow them if needed
in 4.0.
* The ``Twig\Sandbox\SourcePolicyInterface`` interface is deprecated as of Twig
3.26.1 with no replacement. Passing an instance to the
``Twig\Extension\SandboxExtension`` constructor triggers a deprecation.
* Deprecate the ``sandbox`` tag, use the ``sandboxed`` option of the
``include`` function instead:
+4
View File
@@ -28,6 +28,10 @@ final class SandboxExtension extends AbstractExtension
public function __construct(SecurityPolicyInterface $policy, $sandboxed = false, ?SourcePolicyInterface $sourcePolicy = null)
{
if (null !== $sourcePolicy) {
trigger_deprecation('twig/twig', '3.26.1', 'The "%s" interface is deprecated with no replacement, do not pass an instance to "%s".', SourcePolicyInterface::class, self::class);
}
$this->policy = $policy;
$this->sandboxedGlobally = $sandboxed;
$this->sourcePolicy = $sourcePolicy;
+2
View File
@@ -17,6 +17,8 @@ use Twig\Source;
* Interface for a class that can optionally enable the sandbox mode based on a template's Twig\Source.
*
* @author Yaakov Saxon
*
* @deprecated since Twig 3.26.1 with no replacement
*/
interface SourcePolicyInterface
{
+30
View File
@@ -932,8 +932,13 @@ EOF
return $twig;
}
/**
* @group legacy
*/
public function testSandboxSourcePolicyEnableReturningFalse()
{
$this->expectDeprecation('Since twig/twig 3.26.1: The "Twig\Sandbox\SourcePolicyInterface" interface is deprecated with no replacement, do not pass an instance to "Twig\Extension\SandboxExtension".');
$twig = $this->getEnvironment(false, [], self::$templates, [], [], [], [], [], new class implements SourcePolicyInterface {
public function enableSandbox(Source $source): bool
{
@@ -943,8 +948,13 @@ EOF
$this->assertEquals('FOO', $twig->load('1_basic')->render(self::$params));
}
/**
* @group legacy
*/
public function testSandboxSourcePolicyEnableReturningTrue()
{
$this->expectDeprecation('Since twig/twig 3.26.1: The "Twig\Sandbox\SourcePolicyInterface" interface is deprecated with no replacement, do not pass an instance to "Twig\Extension\SandboxExtension".');
$twig = $this->getEnvironment(false, [], self::$templates, [], [], [], [], [], new class implements SourcePolicyInterface {
public function enableSandbox(Source $source): bool
{
@@ -955,8 +965,13 @@ EOF
$twig->load('1_basic')->render([]);
}
/**
* @group legacy
*/
public function testSandboxSourcePolicyFalseDoesntOverrideOtherEnables()
{
$this->expectDeprecation('Since twig/twig 3.26.1: The "Twig\Sandbox\SourcePolicyInterface" interface is deprecated with no replacement, do not pass an instance to "Twig\Extension\SandboxExtension".');
$twig = $this->getEnvironment(true, [], self::$templates, [], [], [], [], [], new class implements SourcePolicyInterface {
public function enableSandbox(Source $source): bool
{
@@ -968,10 +983,14 @@ EOF
}
/**
* @group legacy
*
* @dataProvider provideSourcePolicyArrowBlockedTemplates
*/
public function testSourcePolicyBlocksNonClosureCallableInArrow(string $template)
{
$this->expectDeprecation('Since twig/twig 3.26.1: The "Twig\Sandbox\SourcePolicyInterface" interface is deprecated with no replacement, do not pass an instance to "Twig\Extension\SandboxExtension".');
$sourcePolicy = new class implements SourcePolicyInterface {
public function enableSandbox(Source $source): bool
{
@@ -997,8 +1016,13 @@ EOF
yield 'has every' => ['{{ [1,2] has every "is_int" ? "yes" : "no" }}'];
}
/**
* @group legacy
*/
public function testSourcePolicyAllowsClosureInArrow()
{
$this->expectDeprecation('Since twig/twig 3.26.1: The "Twig\Sandbox\SourcePolicyInterface" interface is deprecated with no replacement, do not pass an instance to "Twig\Extension\SandboxExtension".');
$sourcePolicy = new class implements SourcePolicyInterface {
public function enableSandbox(Source $source): bool
{
@@ -1015,6 +1039,7 @@ EOF
*/
public function testNonSandboxedSourcePolicyAllowsNonClosureCallable()
{
$this->expectDeprecation('Since twig/twig 3.26.1: The "Twig\Sandbox\SourcePolicyInterface" interface is deprecated with no replacement, do not pass an instance to "Twig\Extension\SandboxExtension".');
$this->expectDeprecation('Since twig/twig 3.15: Passing a callable that is not a PHP \Closure as an argument to the "sort" filter is deprecated.');
$sourcePolicy = new class implements SourcePolicyInterface {
@@ -1048,8 +1073,13 @@ EOF
$this->assertSame('foo:off', $twig->load('index')->render([]));
}
/**
* @group legacy
*/
public function testNeedsIsSandboxedFilterFollowsSourcePolicy()
{
$this->expectDeprecation('Since twig/twig 3.26.1: The "Twig\Sandbox\SourcePolicyInterface" interface is deprecated with no replacement, do not pass an instance to "Twig\Extension\SandboxExtension".');
$twig = $this->getEnvironment(false, [], [
'in' => '{{ "foo"|sandbox_aware }}',
'out' => '{{ "foo"|sandbox_aware }}',