From c070e989c4de41441d1061d2678b461f3f13d63b Mon Sep 17 00:00:00 2001 From: Damian Mooyman Date: Wed, 6 Jun 2018 16:45:16 +1200 Subject: [PATCH] BUG Safely handle empty injector factory responses Fixes issue with ImageBackendFactory returning null and breaking injector --- src/Core/Injector/Injector.php | 5 +++++ tests/php/Core/Injector/InjectorTest.php | 16 ++++++++++++++++ .../Core/Injector/InjectorTest/EmptyFactory.php | 13 +++++++++++++ 3 files changed, 34 insertions(+) create mode 100644 tests/php/Core/Injector/InjectorTest/EmptyFactory.php diff --git a/src/Core/Injector/Injector.php b/src/Core/Injector/Injector.php index bf5fc8b54..6b0885132 100644 --- a/src/Core/Injector/Injector.php +++ b/src/Core/Injector/Injector.php @@ -584,6 +584,11 @@ class Injector implements ContainerInterface $factory = isset($spec['factory']) ? $this->get($spec['factory']) : $this->getObjectCreator(); $object = $factory->create($class, $constructorParams); + // Handle empty factory responses + if (!$object) { + return null; + } + // figure out if we have a specific id set or not. In some cases, we might be instantiating objects // that we don't manage directly; we don't want to store these in the service cache below if (!$id) { diff --git a/tests/php/Core/Injector/InjectorTest.php b/tests/php/Core/Injector/InjectorTest.php index d2a42af76..1e54cc1de 100644 --- a/tests/php/Core/Injector/InjectorTest.php +++ b/tests/php/Core/Injector/InjectorTest.php @@ -14,6 +14,7 @@ use SilverStripe\Core\Tests\Injector\InjectorTest\CircularOne; use SilverStripe\Core\Tests\Injector\InjectorTest\CircularTwo; use SilverStripe\Core\Tests\Injector\InjectorTest\ConstructableObject; use SilverStripe\Core\Tests\Injector\InjectorTest\DummyRequirements; +use SilverStripe\Core\Tests\Injector\InjectorTest\EmptyFactory; use SilverStripe\Core\Tests\Injector\InjectorTest\MyChildClass; use SilverStripe\Core\Tests\Injector\InjectorTest\MyParentClass; use SilverStripe\Core\Tests\Injector\InjectorTest\NeedsBothCirculars; @@ -102,6 +103,21 @@ class InjectorTest extends SapphireTest ); } + public function testEmptyFactory() + { + $this->expectException(InjectorNotFoundException::class); + $injector = new Injector(); + $services = array( + 'SomeClass' => array( + 'class' => AnotherService::class, + 'factory' => EmptyFactory::class, + ) + ); + + $injector->load($services); + $injector->create('SomeClass'); + } + public function testConfiguredInjector() { $injector = new Injector(); diff --git a/tests/php/Core/Injector/InjectorTest/EmptyFactory.php b/tests/php/Core/Injector/InjectorTest/EmptyFactory.php new file mode 100644 index 000000000..3354d6b3f --- /dev/null +++ b/tests/php/Core/Injector/InjectorTest/EmptyFactory.php @@ -0,0 +1,13 @@ +