Skip to content

Commit

Permalink
Merge pull request #3913 from chinpei215/master-exception-renderer-fix
Browse files Browse the repository at this point in the history
Fix an infinite recursion caused by missing plugin
  • Loading branch information
markstory committed Jul 9, 2014
2 parents b3dfad6 + 0c1fc36 commit 77455e6
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 0 deletions.
6 changes: 6 additions & 0 deletions lib/Cake/Error/ExceptionRenderer.php
Expand Up @@ -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');
}
Expand Down
67 changes: 67 additions & 0 deletions lib/Cake/Test/Case/Error/ExceptionRendererTest.php
Expand Up @@ -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
Expand Down
11 changes: 11 additions & 0 deletions lib/Cake/Test/test_app/Plugin/TestPlugin/View/Errors/error500.ctp
@@ -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 77455e6

Please sign in to comment.