BUG Check is_callable parent methods before invoke (#10637)

This commit is contained in:
Sabina Talipova 2023-01-12 09:37:48 +13:00 committed by GitHub
parent 2868edd8d9
commit 6d4542561b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 45 additions and 1 deletions

View File

@ -7,6 +7,7 @@ use Exception;
use InvalidArgumentException; use InvalidArgumentException;
use IteratorAggregate; use IteratorAggregate;
use LogicException; use LogicException;
use ReflectionObject;
use SilverStripe\Core\ClassInfo; use SilverStripe\Core\ClassInfo;
use SilverStripe\Core\Config\Config; use SilverStripe\Core\Config\Config;
use SilverStripe\Core\Config\Configurable; use SilverStripe\Core\Config\Configurable;
@ -155,13 +156,22 @@ class ViewableData implements IteratorAggregate
public function __set($property, $value) public function __set($property, $value)
{ {
$this->objCacheClear(); $this->objCacheClear();
if ($this->hasMethod($method = "set$property")) { $method = "set$property";
if ($this->hasMethod($method) && !$this->isPrivate($this, $method)) {
$this->$method($value); $this->$method($value);
} else { } else {
$this->setField($property, $value); $this->setField($property, $value);
} }
} }
private function isPrivate(object $class, string $method): bool
{
$class = new ReflectionObject($class);
return $class->getMethod($method)->isPrivate();
}
/** /**
* Set a failover object to attempt to get data from if it is not present on this object. * Set a failover object to attempt to get data from if it is not present on this object.
* *

View File

@ -2,11 +2,13 @@
namespace SilverStripe\View\Tests; namespace SilverStripe\View\Tests;
use ReflectionMethod;
use SilverStripe\ORM\FieldType\DBField; use SilverStripe\ORM\FieldType\DBField;
use SilverStripe\Dev\SapphireTest; use SilverStripe\Dev\SapphireTest;
use SilverStripe\View\ArrayData; use SilverStripe\View\ArrayData;
use SilverStripe\View\SSViewer; use SilverStripe\View\SSViewer;
use SilverStripe\View\ViewableData; use SilverStripe\View\ViewableData;
use SilverStripe\View\Tests\ViewableDataTestObject;
/** /**
* See {@link SSViewerTest->testCastingHelpers()} for more tests related to casting and ViewableData behaviour, * See {@link SSViewerTest->testCastingHelpers()} for more tests related to casting and ViewableData behaviour,
@ -205,4 +207,17 @@ class ViewableDataTest extends SapphireTest
$this->assertSame($failover, $container->getFailover(), 'getFailover() returned a different object'); $this->assertSame($failover, $container->getFailover(), 'getFailover() returned a different object');
$this->assertFalse($container->hasMethod('testMethod'), 'testMethod() incorrectly reported as existing'); $this->assertFalse($container->hasMethod('testMethod'), 'testMethod() incorrectly reported as existing');
} }
public function testIsPrivate()
{
$reflectionMethod = new ReflectionMethod(ViewableData::class, 'isPrivate');
$reflectionMethod->setAccessible(true);
$object = new ViewableDataTestObject();
$output = $reflectionMethod->invokeArgs($object, [$object, 'privateMethod']);
$this->assertTrue($output, 'Method is not private');
$output = $reflectionMethod->invokeArgs($object, [$object, 'publicMethod']);
$this->assertFalse($output, 'Method is private');
}
} }

View File

@ -0,0 +1,19 @@
<?php
namespace SilverStripe\View\Tests;
use SilverStripe\Dev\TestOnly;
use SilverStripe\ORM\DataObject;
class ViewableDataTestObject extends DataObject implements TestOnly
{
private function privateMethod(): string
{
return 'Private function';
}
public function publicMethod(): string
{
return 'Public function';
}
}