Issue #2386571 by dawehner, hussainweb: Large array structures (e.g. $form) in stack trace results in huge memory usage in FlattenException::flattenArgs()

8.0.x
Nathaniel Catchpole 2014-12-19 09:44:56 +00:00
parent e15ebedc4c
commit dfad7c651b
3 changed files with 3 additions and 59 deletions

View File

@ -14,7 +14,6 @@ use Drupal\Core\ContentNegotiation;
use Drupal\Core\Render\BareHtmlPageRendererInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\Core\Utility\Error;
use Symfony\Component\Debug\Exception\FlattenException;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
@ -87,7 +86,6 @@ class DefaultExceptionSubscriber implements EventSubscriberInterface {
protected function onHtml(GetResponseForExceptionEvent $event) {
$exception = $event->getException();
$error = Error::decodeException($exception);
$flatten_exception = FlattenException::create($exception, 500);
// Display the message if the current error reporting level allows this type
// of message to be displayed, and unconditionally in update.php.
@ -114,7 +112,7 @@ class DefaultExceptionSubscriber implements EventSubscriberInterface {
// Check if verbose error reporting is on.
if ($this->getErrorLevel() == ERROR_REPORTING_DISPLAY_VERBOSE) {
$backtrace_exception = $flatten_exception;
$backtrace_exception = $exception;
while ($backtrace_exception->getPrevious()) {
$backtrace_exception = $backtrace_exception->getPrevious();
}
@ -127,7 +125,7 @@ class DefaultExceptionSubscriber implements EventSubscriberInterface {
// Generate a backtrace containing only scalar argument values. Make
// sure the backtrace is escaped as it can contain user submitted data.
$message .= '<pre class="backtrace">' . SafeMarkup::escape(Error::formatFlattenedBacktrace($backtrace)) . '</pre>';
$message .= '<pre class="backtrace">' . SafeMarkup::escape(Error::formatBacktrace($backtrace)) . '</pre>';
}
drupal_set_message(SafeMarkup::set($message), $class, TRUE);
}

View File

@ -8,7 +8,6 @@
namespace Drupal\Core\EventSubscriber;
use Drupal\Core\ContentNegotiation;
use Symfony\Component\Debug\Exception\FlattenException;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;
@ -88,7 +87,7 @@ abstract class HttpExceptionSubscriberBase implements EventSubscriberInterface {
$exception = $event->getException();
// Make the exception available for example when rendering a block.
$event->getRequest()->attributes->set('exception', FlattenException::create($exception));
$event->getRequest()->attributes->set('exception', $exception);
$handled_formats = $this->getHandledFormats();

View File

@ -187,57 +187,4 @@ class Error {
return $return;
}
/**
* Formats a flattened backtrace into a plain-text string.
*
* The calls show values for scalar arguments and type names for complex ones.
*
* @param array $backtrace
* The backtrace of a Symfony\Component\Debug\Exception\FlattenException.
*
* @return string
* A plain-text line-wrapped string. The string needs to be run through
* SafeMarkup::escape when rendering it as HTML.
*/
public static function formatFlattenedBacktrace(array $backtrace) {
$return = '';
foreach ($backtrace as $trace) {
$call = array('function' => '', 'args' => array());
if (isset($trace['class'])) {
$call['function'] = $trace['class'] . $trace['type'] . $trace['function'];
}
elseif (isset($trace['function'])) {
$call['function'] = $trace['function'];
}
else {
$call['function'] = 'main';
}
if (isset($trace['args'])) {
foreach ($trace['args'] as $arg) {
$type = $arg[0];
$value = $arg[1];
if ($type == 'array') {
$call['args'][] = '[' . ucfirst($type) . ']';
}
elseif ($type == 'null') {
$call['args'][] = strtoupper($type);
}
elseif ($type == 'boolean') {
$call['args'][] = $value ? 'TRUE' : 'FALSE';
}
else {
$call['args'][] = $value;
}
}
}
$return .= $call['function'] . '(' . implode(', ', $call['args']) . ")\n";
}
return $return;
}
}