diff --git a/core/modules/dblog/src/Controller/DbLogController.php b/core/modules/dblog/src/Controller/DbLogController.php index 7c83cce..50cbd47 100644 --- a/core/modules/dblog/src/Controller/DbLogController.php +++ b/core/modules/dblog/src/Controller/DbLogController.php @@ -11,6 +11,7 @@ use Drupal\Core\Extension\ModuleHandlerInterface; use Drupal\Core\Form\FormBuilderInterface; use Drupal\Core\Logger\RfcLogLevel; +use Drupal\Core\Render\Markup; use Drupal\Core\Url; use Drupal\user\Entity\User; use Symfony\Component\DependencyInjection\ContainerInterface; @@ -338,7 +339,7 @@ protected function buildFilterQuery() { * The record from the watchdog table. The object properties are: wid, uid, * severity, type, timestamp, message, variables, link, name. * - * @return string|\Drupal\Core\StringTranslation\TranslatableMarkup|false + * @return \Drupal\Component\Render\MarkupInterface|string|false * The formatted log message or FALSE if the message or variables properties * are not set. */ @@ -347,12 +348,13 @@ public function formatMessage($row) { if (isset($row->message) && isset($row->variables)) { // Messages without variables or user specified text. if ($row->variables === 'N;') { - $message = Xss::filterAdmin($row->message); + $message = $row->message; } // Message to translate with injected variables. else { - $message = $this->t(Xss::filterAdmin($row->message), unserialize($row->variables)); + $message = $this->t($row->message, unserialize($row->variables)); } + $message = Markup::create(Xss::filterAdmin($message)); } else { $message = FALSE; diff --git a/core/modules/dblog/src/Tests/DbLogTest.php b/core/modules/dblog/src/Tests/DbLogTest.php index 111fcfc..b4465ca 100644 --- a/core/modules/dblog/src/Tests/DbLogTest.php +++ b/core/modules/dblog/src/Tests/DbLogTest.php @@ -2,11 +2,14 @@ namespace Drupal\dblog\Tests; +use Drupal\Component\Render\FormattableMarkup; use Drupal\Component\Utility\Html; use Drupal\Component\Utility\Unicode; +use Drupal\Component\Utility\Xss; use Drupal\Core\Logger\RfcLogLevel; use Drupal\Core\Url; use Drupal\dblog\Controller\DbLogController; +use Drupal\language\Entity\ConfigurableLanguage; use Drupal\simpletest\WebTestBase; /** @@ -22,7 +25,7 @@ class DbLogTest extends WebTestBase { * * @var array */ - public static $modules = array('dblog', 'node', 'forum', 'help', 'block'); + public static $modules = array('dblog', 'node', 'forum', 'help', 'block', 'locale'); /** * A user with some relevant administrative permissions. @@ -117,6 +120,91 @@ public function testLogEventPage() { } /** + * Make sure log messages in log pages are properly escaped. + */ + public function testLogEventPageMessageEscaped() { + $this->drupalLogin($this->adminUser); + + $context = [ + 'request_uri' => 'http://example.com?dblog=1', + 'referer' => 'http://example.org?dblog=2', + 'uid' => 0, + 'channel' => 'testing', + 'link' => 'foo/bar', + 'ip' => '0.0.1.0', + 'timestamp' => REQUEST_TIME, + ]; + + // Make sure HTML tags are filtered out in admin/reports/dblog/event/. + \Drupal::service('logger.dblog')->log(RfcLogLevel::NOTICE, " Lorem ipsum", $context); + $wid = db_query('SELECT MAX(wid) FROM {watchdog}')->fetchField(); + + $this->drupalGet('admin/reports/dblog/event/' . $wid); + $this->assertResponse(200); + $this->assertNoRaw(""); + $this->assertRaw("alert('foo'); Lorem ipsum"); + } + + /** + * Make sure log messages in log pages are properly translated and filtered. + */ + public function testLogEventPageMessageTranslated() { + $this->drupalLogin($this->adminUser); + + $langcode = 'ja'; + ConfigurableLanguage::createFromLangcode($langcode)->save(); + $this->config('system.site')->set('default_langcode', $langcode)->save(); + + $text_source = '< > & source @something'; + $text_translation = '< > & translation @something'; + + $locale_storage = $this->container->get('locale.storage'); + + $source = $locale_storage->createString([ + 'source' => $text_source, + ]); + $source->save(); + $translation = $locale_storage->createTranslation([ + 'lid' => $source->lid, + 'language' => $langcode, + 'translation' => $text_translation, + ]); + $translation->save(); + + $translation_manager = $this->container->get('string_translation'); + $translation_manager->reset(); + + $translation_variables = ['@something' => 'foo']; + + $context = $translation_variables + [ + 'request_uri' => 'http://example.com?dblog=1', + 'referer' => 'http://example.org?dblog=2', + 'uid' => 0, + 'channel' => 'testing', + 'link' => 'foo/bar', + 'ip' => '0.0.1.0', + 'timestamp' => REQUEST_TIME, + ]; + + \Drupal::service('logger.dblog')->log(RfcLogLevel::NOTICE, $text_source, $context); + $wid = db_query('SELECT MAX(wid) FROM {watchdog}')->fetchField(); + + // Make sure HTML tags are filtered out after translation. + $this->drupalGet('admin/reports/dblog/event/' . $wid); + $this->assertResponse(200); + + $source_unfiltered = new FormattableMarkup($text_source, $translation_variables); + $source_filtered = Xss::filterAdmin(new FormattableMarkup($text_source, $translation_variables)); + $translation_unfiltered = new FormattableMarkup($text_translation, $translation_variables); + $translation_filtered = Xss::filterAdmin(new FormattableMarkup($text_translation, $translation_variables)); + + $this->assertNoRaw($source_unfiltered); + $this->assertNoRaw($source_filtered); + $this->assertNoRaw($translation_unfiltered); + $this->assertRaw($translation_filtered); + } + + /** * Verifies setting of the database log row limit. * * @param int $row_limit @@ -769,13 +857,6 @@ public function testOverviewLinks() { // Make sure HTML tags are filtered out. $this->assertRaw('title="alert('foo');Lorem ipsum dolor sit amet, consectetur adipiscing & elit. Entry #0"><script>alert('foo');</script>Lorem ipsum dolor sit…'); $this->assertNoRaw(""); - - // Make sure HTML tags are filtered out in admin/reports/dblog/event/ too. - $this->generateLogEntries(1, ['message' => " Lorem ipsum"]); - $wid = db_query('SELECT MAX(wid) FROM {watchdog}')->fetchField(); - $this->drupalGet('admin/reports/dblog/event/' . $wid); - $this->assertNoRaw(""); - $this->assertRaw("alert('foo'); Lorem ipsum"); } }