[Security] made sure that the exception listener is always removed from the event dispatcher at the end of the request

This commit is contained in:
Fabien Potencier 2013-09-08 15:07:37 +02:00
parent b1a062d232
commit 1b2ef74a9a
3 changed files with 30 additions and 7 deletions

View File

@ -13,6 +13,7 @@ namespace Symfony\Component\Security\Http;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\HttpKernel\Event\FinishRequestEvent;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
@ -30,6 +31,7 @@ class Firewall implements EventSubscriberInterface
{
private $map;
private $dispatcher;
private $exceptionListeners;
/**
* Constructor.
@ -41,6 +43,7 @@ class Firewall implements EventSubscriberInterface
{
$this->map = $map;
$this->dispatcher = $dispatcher;
$this->exceptionListeners = new \SplObjectStorage();
}
/**
@ -57,6 +60,7 @@ class Firewall implements EventSubscriberInterface
// register listeners for this firewall
list($listeners, $exception) = $this->map->getListeners($event->getRequest());
if (null !== $exception) {
$this->exceptionListeners[$event->getRequest()] = $exception;
$exception->register($this->dispatcher);
}
@ -70,8 +74,21 @@ class Firewall implements EventSubscriberInterface
}
}
public function onKernelFinishRequest(FinishRequestEvent $event)
{
$request = $event->getRequest();
if (isset($this->exceptionListeners[$request])) {
$this->exceptionListeners[$request]->unregister($this->dispatcher);
unset($this->exceptionListeners[$request]);
}
}
public static function getSubscribedEvents()
{
return array(KernelEvents::REQUEST => array('onKernelRequest', 8));
return array(
KernelEvents::REQUEST => array('onKernelRequest', 8),
KernelEvents::FINISH_REQUEST => 'onKernelFinishRequest',
);
}
}

View File

@ -69,6 +69,16 @@ class ExceptionListener
$dispatcher->addListener(KernelEvents::EXCEPTION, array($this, 'onKernelException'));
}
/**
* Unregisters the dispatcher.
*
* @param EventDispatcherInterface $dispatcher An EventDispatcherInterface instance
*/
public function unregister(EventDispatcherInterface $dispatcher)
{
$dispatcher->removeListener(KernelEvents::EXCEPTION, array($this, 'onKernelException'));
}
/**
* Handles security related exceptions.
*
@ -76,10 +86,6 @@ class ExceptionListener
*/
public function onKernelException(GetResponseForExceptionEvent $event)
{
// we need to remove ourselves as the exception listener can be
// different depending on the Request
$event->getDispatcher()->removeListener(KernelEvents::EXCEPTION, array($this, 'onKernelException'));
$exception = $event->getException();
$request = $event->getRequest();

View File

@ -18,8 +18,8 @@
"require": {
"php": ">=5.3.3",
"symfony/event-dispatcher": "~2.1",
"symfony/http-foundation": "~2.1",
"symfony/http-kernel": "~2.1"
"symfony/http-foundation": "~2.4",
"symfony/http-kernel": "~2.4"
},
"require-dev": {
"symfony/form": "~2.0",