Skip to content

Commit

Permalink
More simple approach for injection loop detection that otherwise woul…
Browse files Browse the repository at this point in the history
…d result in a segfault
  • Loading branch information
Bastian Hofmann committed Jun 22, 2016
1 parent f8d101c commit 9f86f81
Show file tree
Hide file tree
Showing 3 changed files with 206 additions and 0 deletions.
25 changes: 25 additions & 0 deletions src/rg/injektor/DependencyInjectionContainer.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,13 @@ class DependencyInjectionContainer {
*/
private $logger;

/**
* used for injection loop detection
*
* @var array
*/
protected $alreadyVisitedClasses = [];

/**
* @param Configuration $config
*/
Expand Down Expand Up @@ -100,6 +107,22 @@ public function getConfig() {
return $this->config;
}

/**
* @param string $className
* @throws InjectionLoopException
*/
protected function checkForInjectionLoop($className) {
if ($this->iterationDepth > 1000) {
throw new InjectionLoopException(
'Injection loop detected ' . $className . ' ' . $this->iterationDepth . PHP_EOL . print_r(
$this->alreadyVisitedClasses,
true
)
);
}
$this->alreadyVisitedClasses[] = $className;
}

/**
* @param string $fullClassName
* @param array $constructorArguments
Expand All @@ -116,6 +139,8 @@ public function getInstanceOfClass($fullClassName, array $constructorArguments =

$this->log('Trying to get instance of [' . $fullClassName . ']');

$this->checkForInjectionLoop($fullClassName);

$classConfig = $this->config->getClassConfig($fullClassName);

if ($configuredInstance = $this->getConfiguredInstance($classConfig)) {
Expand Down
6 changes: 6 additions & 0 deletions src/rg/injektor/InjectionLoopException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<?php
namespace rg\injektor;

class InjectionLoopException extends InjectionException {

}
175 changes: 175 additions & 0 deletions test/rg/injektor/InjectionLoopDetectionTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
<?php
namespace rg\injektor;

class InjectionLoopDetectionTest extends \PHPUnit_Framework_TestCase {

/**
* @expectedException \rg\injektor\InjectionLoopException
*/
public function testInjectionLoopDetectionA() {
$config = new Configuration();
$dic = new DependencyInjectionContainer($config);

$dic->getInstanceOfClass(InjectionLoopDetectionTest_DepA::class);
}

/**
* @expectedException \rg\injektor\InjectionLoopException
*/
public function testInjectionLoopDetectionB() {
$config = new Configuration();
$dic = new DependencyInjectionContainer($config);

$dic->getInstanceOfClass(InjectionLoopDetectionTest_DepB::class);
}

/**
* @expectedException \rg\injektor\InjectionLoopException
*/
public function testInjectionLoopDetectionC() {
$config = new Configuration();
$dic = new DependencyInjectionContainer($config);

$dic->getInstanceOfClass(InjectionLoopDetectionTest_DepC::class);
}

/**
* @expectedException \rg\injektor\InjectionLoopException
*/
public function testInjectionLoopDetectionD() {
$config = new Configuration();
$dic = new DependencyInjectionContainer($config);

$dic->getInstanceOfClass(InjectionLoopDetectionTest_DepD::class);
}

/**
* @expectedException \rg\injektor\InjectionLoopException
*/
public function testInjectionLoopDetectionE() {
$config = new Configuration();
$dic = new DependencyInjectionContainer($config);

$dic->getInstanceOfClass(InjectionLoopDetectionTest_DepE::class);
}

public function testInjectionLoopDetectionNoRecA() {
$config = new Configuration();
$dic = new DependencyInjectionContainer($config);

$this->assertInstanceOf(InjectionLoopDetectionTest_NoRecA::class, $dic->getInstanceOfClass(InjectionLoopDetectionTest_NoRecA::class));
}
}

class InjectionLoopDetectionTest_DepA {

/**
* @inject
* @param InjectionLoopDetectionTest_DepB $dep
*/
public function __construct(InjectionLoopDetectionTest_DepB $dep) {

}
}

class InjectionLoopDetectionTest_DepB {

/**
* @inject
* @param InjectionLoopDetectionTest_DepC $dep
*/
public function __construct(InjectionLoopDetectionTest_DepC $dep) {

}
}

class InjectionLoopDetectionTest_DepC {

/**
* @inject
* @param InjectionLoopDetectionTest_DepA $dep
*/
public function __construct(InjectionLoopDetectionTest_DepA $dep) {

}
}

class InjectionLoopDetectionTest_DepD {

/**
* @inject
* @param InjectionLoopDetectionTest_DepD $dep
*/
public function __construct(InjectionLoopDetectionTest_DepD $dep) {

}
}

class InjectionLoopDetectionTest_DepE {

/**
* @inject
* @param InjectionLoopDetectionTest_DepD $dep
*/
public function __construct(InjectionLoopDetectionTest_DepD $dep) {

}
}

class InjectionLoopDetectionTest_NoRecA {

/**
* @inject
* @param InjectionLoopDetectionTest_NoRecB $dep
* @param InjectionLoopDetectionTest_NoRecC $dep2
*/
public function __construct(
InjectionLoopDetectionTest_NoRecC $dep3,
InjectionLoopDetectionTest_NoRecBA $dep2,
InjectionLoopDetectionTest_NoRecB $dep) {

}
}

class InjectionLoopDetectionTest_NoRecBA {

/**
* @inject
* @param InjectionLoopDetectionTest_NoRecB $dep
*/
public function __construct(InjectionLoopDetectionTest_NoRecB $dep) {

}
}

class InjectionLoopDetectionTest_NoRecB {

/**
* @inject
* @param InjectionLoopDetectionTest_NoRecD $dep
*/
public function __construct(InjectionLoopDetectionTest_NoRecD $dep) {

}
}

class InjectionLoopDetectionTest_NoRecC {

/**
* @inject
* @param InjectionLoopDetectionTest_NoRecD $dep
*/
public function __construct(InjectionLoopDetectionTest_NoRecD $dep) {

}
}

class InjectionLoopDetectionTest_NoRecD {

/**
* @inject
*/
public function __construct() {

}
}

0 comments on commit 9f86f81

Please sign in to comment.