mirror of
https://github.com/twigphp/Twig.git
synced 2026-09-05 23:17:26 +00:00
Add sandbox tests for methods routed through __call()
This commit is contained in:
@@ -771,6 +771,54 @@ class SandboxTest extends TestCase
|
||||
}
|
||||
}
|
||||
|
||||
public function testSandboxAllowedMagicCallMethod(): void
|
||||
{
|
||||
$twig = $this->getEnvironment(true, [], ['index' => '{{ o.hello }}'], [], [], [MagicCallObject::class => 'hello']);
|
||||
$this->assertSame('call:hello', $twig->load('index')->render(['o' => new MagicCallObject()]), 'Sandbox allows a virtual method routed through __call() when its name is allowed');
|
||||
}
|
||||
|
||||
public function testSandboxUnallowedMagicCallMethod(): void
|
||||
{
|
||||
$twig = $this->getEnvironment(true, [], ['index' => '{{ o.hello }}']);
|
||||
try {
|
||||
$twig->load('index')->render(['o' => new MagicCallObject()]);
|
||||
$this->fail('Sandbox throws a SecurityError exception if a virtual method routed through __call() is not allowed');
|
||||
} catch (SecurityNotAllowedPropertyError $e) {
|
||||
$this->assertEquals(MagicCallObject::class, $e->getClassName());
|
||||
$this->assertEquals('hello', $e->getPropertyName());
|
||||
}
|
||||
}
|
||||
|
||||
public function testSandboxUnallowedMagicCallMethodWithMethodSyntax(): void
|
||||
{
|
||||
$twig = $this->getEnvironment(true, [], ['index' => '{{ o.hello() }}']);
|
||||
try {
|
||||
$twig->load('index')->render(['o' => new MagicCallObject()]);
|
||||
$this->fail('Sandbox throws a SecurityError exception if a virtual method routed through __call() is not allowed');
|
||||
} catch (SecurityNotAllowedMethodError $e) {
|
||||
$this->assertEquals(MagicCallObject::class, $e->getClassName());
|
||||
$this->assertEquals('hello', $e->getMethodName());
|
||||
}
|
||||
}
|
||||
|
||||
public function testSandboxAllowingCallLiteralDoesNotAllowMagicCallMethod(): void
|
||||
{
|
||||
$twig = $this->getEnvironment(true, [], ['index' => '{{ o.hello }}'], [], [], [MagicCallObject::class => '__call']);
|
||||
try {
|
||||
$twig->load('index')->render(['o' => new MagicCallObject()]);
|
||||
$this->fail('Sandbox does not allow every virtual method just because "__call" is allowed');
|
||||
} catch (SecurityNotAllowedPropertyError $e) {
|
||||
$this->assertEquals(MagicCallObject::class, $e->getClassName());
|
||||
$this->assertEquals('hello', $e->getPropertyName());
|
||||
}
|
||||
}
|
||||
|
||||
public function testSandboxFallsBackToMagicCallMethodForUnallowedProperty(): void
|
||||
{
|
||||
$twig = $this->getEnvironment(true, [], ['index' => '{{ o.secret }}'], [], [], [MagicCallObject::class => 'secret']);
|
||||
$this->assertSame('call:secret', $twig->load('index')->render(['o' => new MagicCallObject()]), 'Sandbox falls back to __call() when a real property is not allowed but the method is');
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider getSandboxUnallowedToStringTests
|
||||
*/
|
||||
@@ -2560,6 +2608,16 @@ class MagicObject
|
||||
}
|
||||
}
|
||||
|
||||
class MagicCallObject
|
||||
{
|
||||
public $secret = 'secret';
|
||||
|
||||
public function __call($name, $arguments)
|
||||
{
|
||||
return 'call:'.$name;
|
||||
}
|
||||
}
|
||||
|
||||
// Plain object without __toString: column tests exercise property access, not
|
||||
// string coercion, so the array elements must not be Stringable to avoid
|
||||
// triggering the generic filter-input __toString sandbox check.
|
||||
|
||||
Reference in New Issue
Block a user