diff --git a/core/modules/dblog/src/Controller/DbLogController.php b/core/modules/dblog/src/Controller/DbLogController.php index 89e5dc2..69a2d3e 100644 --- a/core/modules/dblog/src/Controller/DbLogController.php +++ b/core/modules/dblog/src/Controller/DbLogController.php @@ -7,6 +7,7 @@ namespace Drupal\dblog\Controller; +use Drupal\Component\Utility\SafeMarkup; use Drupal\Component\Utility\Unicode; use Drupal\Component\Utility\String; use Drupal\Component\Utility\Xss; @@ -238,6 +239,13 @@ public function eventDetails($event_id) { '#theme' => 'username', '#account' => user_load($dblog->uid), ); + // Validate the event link if it is safe. + if (!SafeMarkup::isSafe($dblog->link)) { + $event_link = Xss::filterAdmin($dblog->link); + } + else { + $event_link = $dblog->link; + } $rows = array( array( array('data' => $this->t('Type'), 'header' => TRUE), @@ -253,11 +261,11 @@ public function eventDetails($event_id) { ), array( array('data' => $this->t('Location'), 'header' => TRUE), - _l($dblog->location, $dblog->location), + $this->l($dblog->location, Url::fromUri($dblog->location)), ), array( array('data' => $this->t('Referrer'), 'header' => TRUE), - _l($dblog->referer, $dblog->referer), + $this->l($dblog->referer, Url::fromUri($dblog->referer)), ), array( array('data' => $this->t('Message'), 'header' => TRUE), @@ -273,7 +281,7 @@ public function eventDetails($event_id) { ), array( array('data' => $this->t('Operations'), 'header' => TRUE), - $dblog->link, + $event_link, ), ); $build['dblog_table'] = array( diff --git a/core/modules/dblog/src/Tests/DbLogTest.php b/core/modules/dblog/src/Tests/DbLogTest.php index 2ef242d..de3acf7 100644 --- a/core/modules/dblog/src/Tests/DbLogTest.php +++ b/core/modules/dblog/src/Tests/DbLogTest.php @@ -10,7 +10,7 @@ use Drupal\Component\Utility\Xss; use Drupal\dblog\Controller\DbLogController; use Drupal\simpletest\WebTestBase; - +use Drupal\Core\Url; /** * Generate events and verify dblog entries; verify user access to log reports * based on persmissions. @@ -65,6 +65,8 @@ function testDbLog() { $this->verifyEvents(); $this->verifyReports(); $this->verifyBreadcrumbs(); + $this->verifyLinkEscaping(); + // Verify the overview table sorting. $orders = array('Date', 'Type', 'User'); $sorts = array('asc', 'desc'); @@ -123,20 +125,18 @@ private function verifyCron($row_limit) { * * @param int $count * Number of watchdog entries to generate. - * @param string $type - * (optional) The type of watchdog entry. Defaults to 'custom'. - * @param int $severity - * (optional) The severity of the watchdog entry. Defaults to WATCHDOG_NOTICE. + * @param array $options + * (optional) An array of options that override the default values. */ - private function generateLogEntries($count, $type = 'custom', $severity = WATCHDOG_NOTICE) { + private function generateLogEntries($count, $options = array()) { global $base_root; // Prepare the fields to be logged - $log = array( - 'channel' => $type, - 'message' => 'Log entry added to test the dblog row limit.', + $log = $options + array( + 'channel' => 'system', + 'message' => 'Dblog test log message', 'variables' => array(), - 'severity' => $severity, + 'severity' => WATCHDOG_NOTICE, 'link' => NULL, 'user' => $this->big_user, 'uid' => $this->big_user->id(), @@ -145,10 +145,18 @@ private function generateLogEntries($count, $type = 'custom', $severity = WATCHD 'ip' => '127.0.0.1', 'timestamp' => REQUEST_TIME, ); - $message = 'Log entry added to test the dblog row limit. Entry #'; - for ($i = 0; $i < $count; $i++) { - $log['message'] = $message . $i; - $this->container->get('logger.dblog')->log($severity, $log['message'], $log); + + if ($count > 1) { + $row_message = $log['message'] . ' Entry #'; + for ($i = 0; $i < $count; $i++) { + $log['message'] = $row_message . $i; + $this->container->get('logger.dblog') + ->log($log['severity'], $log['message'], $log); + } + } + else { + $this->container->get('logger.dblog') + ->log($log['severity'], $log['message'], $log); } } @@ -240,6 +248,25 @@ public function verifySort($sort = 'asc', $order = 'Date') { } /** + * Test the escaping of links in the operation row of a database log detail + * page. + */ + private function verifyLinkEscaping() { + $link = \Drupal::l('View', Url::fromRoute('entity.node.canonical', array('node' => 1))); + $message = 'Log entry added to do the verifyLinkEscaping test.'; + $this->generateLogEntries(1, array( + 'message' => $message, + 'link' => $link, + )); + + $result = db_query_range('SELECT wid FROM {watchdog} ORDER BY wid DESC', 0, 1); + $this->drupalGet('admin/reports/dblog/event/' . $result->fetchField()); + + // Check if the link exists (unescaped). + $this->assertRaw($link); + } + + /** * Generates and then verifies some user events. */ private function doUser() { @@ -441,21 +468,11 @@ protected function testDBLogAddAndClear() { global $base_root; // Get a count of how many watchdog entries already exist. $count = db_query('SELECT COUNT(*) FROM {watchdog}')->fetchField(); - $log = array( - 'channel' => 'system', - 'message' => 'Log entry added to test the doClearTest clear down.', - 'variables' => array(), - 'severity' => WATCHDOG_NOTICE, - 'link' => NULL, - 'user' => $this->big_user, - 'uid' => $this->big_user->id(), - 'request_uri' => $base_root . request_uri(), - 'referer' => \Drupal::request()->server->get('HTTP_REFERER'), - 'ip' => '127.0.0.1', - 'timestamp' => REQUEST_TIME, - ); - // Add a watchdog entry. - $this->container->get('logger.dblog')->log($log['severity'], $log['message'], $log); + $this->generateLogEntries(1, array( + 'message' => 'Log entry added to test the doClearTest clear down.', + 'channel' => 'system', + )); + // Make sure the table count has actually been incremented. $this->assertEqual($count + 1, db_query('SELECT COUNT(*) FROM {watchdog}')->fetchField(), format_string('dblog_watchdog() added an entry to the dblog :count', array(':count' => $count))); // Login the admin user. @@ -490,7 +507,10 @@ protected function testFilter() { 'type' => $type_name, 'severity' => $severity++, ); - $this->generateLogEntries($type['count'], $type['type'], $type['severity']); + $this->generateLogEntries($type['count'], array( + 'channel' => $type['type'], + 'severity' => $type['severity'], + )); } }