Skip to content
Permalink
Browse files

Fix an infinite recursion caused by missing plugin

When a MissingPluginException has caught when rendering an exception,
we should disable the plugin as needed to prevent an infinite recursion.
  • Loading branch information...
chinpei215 committed Jul 8, 2014
1 parent b3dfad6 commit 0c1fc36b14f4cd3a00ba5954f36d4bd577980125
@@ -285,6 +285,12 @@ protected function _outputMessage($template) {
} else {
$this->_outputMessage('error500');
}
} catch (MissingPluginException $e) {
$attributes = $e->getAttributes();
if (isset($attributes['plugin']) && $attributes['plugin'] === $this->controller->plugin) {
$this->controller->plugin = null;
}
$this->_outputMessageSafe('error500');
} catch (Exception $e) {
$this->_outputMessageSafe('error500');
}
@@ -764,6 +764,73 @@ public function testMissingSubdirRenderSafe() {
$this->assertEquals('Errors', $ExceptionRenderer->controller->viewPath);
}
/**
* Test that missing plugin disables Controller::$plugin if the two are the same plugin.
*
* @return void
*/
public function testMissingPluginRenderSafe() {
$exception = new NotFoundException();
$ExceptionRenderer = new ExceptionRenderer($exception);
$ExceptionRenderer->controller = $this->getMock('Controller', array('render'));
$ExceptionRenderer->controller->plugin = 'TestPlugin';
$ExceptionRenderer->controller->request = $this->getMock('CakeRequest');
$exception = new MissingPluginException(array('plugin' => 'TestPlugin'));
$ExceptionRenderer->controller->expects($this->once())
->method('render')
->with('error400')
->will($this->throwException($exception));
$response = $this->getMock('CakeResponse');
$response->expects($this->once())
->method('body')
->with($this->logicalAnd(
$this->logicalNot($this->stringContains('test plugin error500')),
$this->stringContains('Not Found')
));
$ExceptionRenderer->controller->response = $response;
$ExceptionRenderer->render();
}
/**
* Test that missing plugin doesn't disable Controller::$plugin if the two aren't the same plugin.
*
* @return void
*/
public function testMissingPluginRenderSafeWithPlugin() {
App::build(array(
'Plugin' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS)
), App::RESET);
CakePlugin::load('TestPlugin');
$exception = new NotFoundException();
$ExceptionRenderer = new ExceptionRenderer($exception);
$ExceptionRenderer->controller = $this->getMock('Controller', array('render'));
$ExceptionRenderer->controller->plugin = 'TestPlugin';
$ExceptionRenderer->controller->request = $this->getMock('CakeRequest');
$exception = new MissingPluginException(array('plugin' => 'TestPluginTwo'));
$ExceptionRenderer->controller->expects($this->once())
->method('render')
->with('error400')
->will($this->throwException($exception));
$response = $this->getMock('CakeResponse');
$response->expects($this->once())
->method('body')
->with($this->logicalAnd(
$this->stringContains('test plugin error500'),
$this->stringContains('Not Found')
));
$ExceptionRenderer->controller->response = $response;
$ExceptionRenderer->render();
CakePlugin::unload();
}
/**
* Test that exceptions can be rendered when an request hasn't been registered
* with Router
@@ -0,0 +1,11 @@
test plugin error500
<h2><?php echo $message; ?></h2>
<p class="error">
<strong><?php echo __d('cake', 'Error'); ?>: </strong>
<?php echo __d('cake', 'An Internal Error Has Occurred.'); ?>
</p>
<?php
if (Configure::read('debug') > 0):
echo $this->element('exception_stack_trace');
endif;
?>

0 comments on commit 0c1fc36

Please sign in to comment.
You can’t perform that action at this time.