From ab190206e75a11316753a73decffd5516e6945b9 Mon Sep 17 00:00:00 2001
From: Angie Byron <webchick@24967.no-reply.drupal.org>
Date: Sat, 16 Oct 2010 00:00:17 +0000
Subject: [PATCH] #642160 by boombatower, Damien Tournoud: Make debug() message
 more usable.

---
 includes/common.inc                 |  6 +++++-
 includes/errors.inc                 | 28 +++++++++++++++++++---------
 modules/simpletest/tests/error.test | 16 ++++++++--------
 modules/system/system.test          |  2 +-
 4 files changed, 33 insertions(+), 19 deletions(-)

diff --git a/includes/common.inc b/includes/common.inc
index b6c6177c8461..bde006f425bf 100644
--- a/includes/common.inc
+++ b/includes/common.inc
@@ -6841,7 +6841,11 @@ function _drupal_flush_css_js() {
  */
 function debug($data, $label = NULL, $print_r = FALSE) {
   // Print $data contents to string.
-  $string = $print_r ? print_r($data, TRUE) : var_export($data, TRUE);
+  $string = check_plain($print_r ? print_r($data, TRUE) : var_export($data, TRUE));
+
+  // Display values with pre-formatting to increase readability.
+  $string = '<pre>' . $string . '</pre>';
+
   trigger_error(trim($label ? "$label: $string" : $string));
 }
 
diff --git a/includes/errors.inc b/includes/errors.inc
index 990f60cfd2cd..235c16141d00 100644
--- a/includes/errors.inc
+++ b/includes/errors.inc
@@ -70,10 +70,16 @@ function _drupal_error_handler_real($error_level, $message, $filename, $line, $c
     list($severity_msg, $severity_level) = $types[$error_level];
     $caller = _drupal_get_last_caller(debug_backtrace());
 
+    if (!function_exists('filter_xss_admin')) {
+      require_once DRUPAL_ROOT . '/includes/common.inc';
+    }
+
     // We treat recoverable errors as fatal.
     _drupal_log_error(array(
       '%type' => isset($types[$error_level]) ? $severity_msg : 'Unknown error',
-      '%message' => $message,
+      // The standard PHP error handler considers that the error messages
+      // are HTML. We mimick this behavior here.
+      '!message' => filter_xss_admin($message),
       '%function' => $caller['function'],
       '%file' => $caller['file'],
       '%line' => $caller['line'],
@@ -118,7 +124,9 @@ function _drupal_decode_exception($exception) {
 
   return array(
     '%type' => get_class($exception),
-    '%message' => $message,
+    // The standard PHP exception handler considers that the exception message
+    // is plain-text. We mimick this behavior here.
+    '!message' => check_plain($message),
     '%function' => $caller['function'],
     '%file' => $caller['file'],
     '%line' => $caller['line'],
@@ -135,7 +143,7 @@ function _drupal_decode_exception($exception) {
  *   An error message.
  */
 function _drupal_render_exception_safe($exception) {
-  return check_plain(strtr('%type: %message in %function (line %line of %file).', _drupal_decode_exception($exception)));
+  return check_plain(strtr('%type: !message in %function (line %line of %file).', _drupal_decode_exception($exception)));
 }
 
 /**
@@ -165,7 +173,9 @@ function error_displayable($error = NULL) {
  * Log a PHP error or exception, display an error page in fatal cases.
  *
  * @param $error
- *   An array with the following keys: %type, %message, %function, %file, %line.
+ *   An array with the following keys: %type, !message, %function, %file, %line.
+ *   All the parameters are plain-text, exception message, which needs to be
+ *   a safe HTML string.
  * @param $fatal
  *   TRUE if the error is fatal.
  */
@@ -188,7 +198,7 @@ function _drupal_log_error($error, $fatal = FALSE) {
     // as it uniquely identifies each PHP error.
     static $number = 0;
     $assertion = array(
-      $error['%message'],
+      $error['!message'],
       $error['%type'],
       array(
         'function' => $error['%function'],
@@ -200,7 +210,7 @@ function _drupal_log_error($error, $fatal = FALSE) {
     $number++;
   }
 
-  watchdog('php', '%type: %message in %function (line %line of %file).', $error, $error['severity_level']);
+  watchdog('php', '%type: !message in %function (line %line of %file).', $error, $error['severity_level']);
 
   if ($fatal) {
     drupal_add_http_header('Status', '500 Service unavailable (with message)');
@@ -209,7 +219,7 @@ function _drupal_log_error($error, $fatal = FALSE) {
   if (drupal_is_cli()) {
     if ($fatal) {
       // When called from CLI, simply output a plain text message.
-      print html_entity_decode(strip_tags(t('%type: %message in %function (line %line of %file).', $error))). "\n";
+      print html_entity_decode(strip_tags(t('%type: !message in %function (line %line of %file).', $error))). "\n";
       exit;
     }
   }
@@ -217,7 +227,7 @@ function _drupal_log_error($error, $fatal = FALSE) {
   if (isset($_SERVER['HTTP_X_REQUESTED_WITH']) && $_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest') {
     if ($fatal) {
       // When called from JavaScript, simply output the error message.
-      print t('%type: %message in %function (line %line of %file).', $error);
+      print t('%type: !message in %function (line %line of %file).', $error);
       exit;
     }
   }
@@ -234,7 +244,7 @@ function _drupal_log_error($error, $fatal = FALSE) {
         $class = 'status';
       }
 
-      drupal_set_message(t('%type: %message in %function (line %line of %file).', $error), $class);
+      drupal_set_message(t('%type: !message in %function (line %line of %file).', $error), $class);
     }
 
     if ($fatal) {
diff --git a/modules/simpletest/tests/error.test b/modules/simpletest/tests/error.test
index fe4ee4526e38..fdaab2bb82af 100644
--- a/modules/simpletest/tests/error.test
+++ b/modules/simpletest/tests/error.test
@@ -23,21 +23,21 @@ class DrupalErrorHandlerUnitTest extends DrupalWebTestCase {
   function testErrorHandler() {
     $error_notice = array(
       '%type' => 'Notice',
-      '%message' => 'Undefined variable: bananas',
+      '!message' => 'Undefined variable: bananas',
       '%function' => 'error_test_generate_warnings()',
       '%line' => 44,
       '%file' => drupal_realpath('modules/simpletest/tests/error_test.module'),
     );
     $error_warning = array(
       '%type' => 'Warning',
-      '%message' => 'Division by zero',
+      '!message' => 'Division by zero',
       '%function' => 'error_test_generate_warnings()',
       '%line' => 46,
       '%file' => drupal_realpath('modules/simpletest/tests/error_test.module'),
     );
     $error_user_notice = array(
       '%type' => 'User warning',
-      '%message' => 'Drupal is awesome',
+      '!message' => 'Drupal is awesome',
       '%function' => 'error_test_generate_warnings()',
       '%line' => 48,
       '%file' => drupal_realpath('modules/simpletest/tests/error_test.module'),
@@ -74,14 +74,14 @@ class DrupalErrorHandlerUnitTest extends DrupalWebTestCase {
   function testExceptionHandler() {
     $error_exception = array(
       '%type' => 'Exception',
-      '%message' => 'Drupal is awesome',
+      '!message' => 'Drupal is awesome',
       '%function' => 'error_test_trigger_exception()',
       '%line' => 57,
       '%file' => drupal_realpath('modules/simpletest/tests/error_test.module'),
     );
     $error_pdo_exception = array(
       '%type' => 'PDOException',
-      '%message' => 'SELECT * FROM bananas_are_awesome',
+      '!message' => 'SELECT * FROM bananas_are_awesome',
       '%function' => 'error_test_trigger_pdo_exception()',
       '%line' => 65,
       '%file' => drupal_realpath('modules/simpletest/tests/error_test.module'),
@@ -96,7 +96,7 @@ class DrupalErrorHandlerUnitTest extends DrupalWebTestCase {
     // We cannot use assertErrorMessage() since the extact error reported
     // varies from database to database. Check that the SQL string is displayed.
     $this->assertText($error_pdo_exception['%type'], t('Found %type in error page.', $error_pdo_exception));
-    $this->assertText($error_pdo_exception['%message'], t('Found %message in error page.', $error_pdo_exception));
+    $this->assertText($error_pdo_exception['!message'], t('Found !message in error page.', $error_pdo_exception));
     $error_details = t('in %function (line %line of %file)', $error_pdo_exception);
     $this->assertRaw($error_details, t("Found '!message' in error page.", array('!message' => $error_details)));
   }
@@ -105,7 +105,7 @@ class DrupalErrorHandlerUnitTest extends DrupalWebTestCase {
    * Helper function: assert that the error message is found.
    */
   function assertErrorMessage(array $error) {
-    $message = t('%type: %message in %function (line %line of %file).', $error);
+    $message = t('%type: !message in %function (line %line of %file).', $error);
     $this->assertRaw($message, t('Error !message found.', array('!message' => $message)));
   }
 
@@ -113,7 +113,7 @@ class DrupalErrorHandlerUnitTest extends DrupalWebTestCase {
    * Helper function: assert that the error message is not found.
    */
   function assertNoErrorMessage(array $error) {
-    $message = t('%type: %message in %function (line %line of %file).', $error);
+    $message = t('%type: !message in %function (line %line of %file).', $error);
     $this->assertNoRaw($message, t('Error !message not found.', array('!message' => $message)));
   }
 }
diff --git a/modules/system/system.test b/modules/system/system.test
index da7042ac2ce0..511c9c28e63d 100644
--- a/modules/system/system.test
+++ b/modules/system/system.test
@@ -1942,7 +1942,7 @@ class ShutdownFunctionsTest extends DrupalWebTestCase {
 
     // Make sure exceptions displayed through _drupal_render_exception_safe()
     // are correctly escaped.
-    $this->assertText('Drupal is &lt;blink&gt;awesome&lt;/blink&gt;.');
+    $this->assertRaw('Drupal is &amp;lt;blink&amp;gt;awesome&amp;lt;/blink&amp;gt;.');
   }
 }
 
-- 
GitLab