Skip to content

Commit 6676620

Browse files
committedSep 5, 2024
Fix recursion in Container Proxy (#1140)
1 parent 4e83c4a commit 6676620

File tree

4 files changed

+43
-0
lines changed

4 files changed

+43
-0
lines changed
 
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Spiral\Core\Exception\Container;
6+
7+
/**
8+
* Recursion can occur due to improper container configuration or
9+
* an unplanned exit from the scope by the execution thread.
10+
*/
11+
class RecursiveProxyException extends ContainerException
12+
{
13+
}

‎src/Internal/Proxy.php

+5
Original file line numberDiff line numberDiff line change
@@ -86,4 +86,9 @@ public static function create(
8686

8787
return $instance;
8888
}
89+
90+
public static function isProxy(object $object): bool
91+
{
92+
return \in_array($object::class, self::$classes, true);
93+
}
8994
}

‎src/Internal/Proxy/Resolver.php

+8
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
use Psr\Container\ContainerInterface;
88
use Spiral\Core\ContainerScope;
99
use Spiral\Core\Exception\Container\ContainerException;
10+
use Spiral\Core\Exception\Container\RecursiveProxyException;
11+
use Spiral\Core\Internal\Proxy;
1012

1113
/**
1214
* @internal
@@ -32,6 +34,12 @@ public static function resolve(
3234
);
3335
}
3436

37+
if (Proxy::isProxy($result)) {
38+
throw new RecursiveProxyException(
39+
\sprintf('Recursive proxy detected for `%s`.', $alias),
40+
);
41+
}
42+
3543
return $result;
3644
}
3745
}

‎tests/Scope/ProxyTest.php

+17
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
use Spiral\Core\Attribute\Proxy;
1010
use Spiral\Core\Container;
1111
use Spiral\Core\Container\InjectorInterface;
12+
use Spiral\Core\Exception\Container\RecursiveProxyException;
1213
use Spiral\Core\Scope;
1314
use Spiral\Tests\Core\Scope\Stub\Context;
1415
use Spiral\Tests\Core\Scope\Stub\ContextInterface;
@@ -296,6 +297,22 @@ public function __toString(): string
296297
);
297298
}
298299

300+
/**
301+
* Proxy gets a proxy of the same type.
302+
*/
303+
public function testRecursiveProxy(): void
304+
{
305+
$root = new Container();
306+
$root->bind(UserInterface::class, new \Spiral\Core\Config\Proxy(UserInterface::class));
307+
308+
$this->expectException(RecursiveProxyException::class);
309+
310+
$root->runScope(
311+
new Scope(),
312+
fn(#[Proxy] UserInterface $user) => $user->getName(),
313+
);
314+
}
315+
299316
/*
300317
// Proxy::$attachContainer=true tests
301318

0 commit comments

Comments
 (0)