diff --git a/core/lib/Drupal/Core/Menu/MenuLinkManager.php b/core/lib/Drupal/Core/Menu/MenuLinkManager.php index 44eeeb3..0cc7727 100644 --- a/core/lib/Drupal/Core/Menu/MenuLinkManager.php +++ b/core/lib/Drupal/Core/Menu/MenuLinkManager.php @@ -44,7 +44,8 @@ class MenuLinkManager implements MenuLinkManagerInterface { // The static title for the menu link. If this came from a YAML definition // or other safe source this may be a TranslationWrapper object. 'title' => '', - // The description. + // The description. If this came from a YAML definition or other safe source + // this maybe be a TranslationWrapper object. 'description' => '', // The plugin ID of the parent link (or NULL for a top-level link). 'parent' => '', diff --git a/core/lib/Drupal/Core/Menu/MenuTreeStorage.php b/core/lib/Drupal/Core/Menu/MenuTreeStorage.php index 11e3711..92b5454 100644 --- a/core/lib/Drupal/Core/Menu/MenuTreeStorage.php +++ b/core/lib/Drupal/Core/Menu/MenuTreeStorage.php @@ -1250,14 +1250,14 @@ protected static function schemaDefinition() { 'default' => '', ), 'title' => array( - 'description' => 'The title for the link. May be a serialized TranslationWrapper', + 'description' => 'The serialized title for the link. May be a TranslationWrapper', 'type' => 'blob', 'size' => 'big', 'not null' => FALSE, 'serialize' => TRUE, ), 'description' => array( - 'description' => 'The description of this link - used for admin pages and title attribute.', + 'description' => 'The serialized description of this link - used for admin pages and title attribute. May be a TranslationWrapper.', 'type' => 'blob', 'size' => 'big', 'not null' => FALSE, diff --git a/core/modules/system/src/Tests/Menu/MenuLinkSecurityTest.php b/core/modules/system/src/Tests/Menu/MenuLinkSecurityTest.php new file mode 100644 index 0000000..2fe6c3b --- /dev/null +++ b/core/modules/system/src/Tests/Menu/MenuLinkSecurityTest.php @@ -0,0 +1,45 @@ + '', + 'menu_name' => 'tools', + 'link' => ['uri' => 'route:'], + ]); + $menu_link_content->save(); + + $this->drupalPlaceBlock('system_menu_block:tools'); + + $this->drupalGet(''); + $this->assertNoRaw(''); + $this->assertNoRaw(''); + $this->assertRaw(htmlspecialchars('', ENT_QUOTES, 'UTF-8')); + $this->assertRaw(htmlspecialchars('', ENT_QUOTES, 'UTF-8')); + } + +} diff --git a/core/modules/system/src/Tests/Update/MenuTreeSerializationTitleTest.php b/core/modules/system/src/Tests/Update/MenuTreeSerializationTitleTest.php new file mode 100644 index 0000000..b9e247f --- /dev/null +++ b/core/modules/system/src/Tests/Update/MenuTreeSerializationTitleTest.php @@ -0,0 +1,49 @@ +databaseDumpFiles = [ + __DIR__ . '/../../../tests/fixtures/update/drupal-8.bare.standard.php.gz', + ]; + parent::setUp(); + } + + /** + * Ensures that the system_update_8001() runs as expected. + */ + public function testUpdate() { + $this->runUpdates(); + + // Ensure that some fields got dropped. + $this->assertFalse(db_field_exists('menu_tree', 'title_arguments')); + $this->assertFalse(db_field_exists('menu_tree', 'title_contexts')); + + // Ensure that all titles/descriptions are unserializable. + $select = \Drupal::database()->select('menu_tree'); + $result = $select->fields('menu_tree', ['mlid', 'title', 'description']) + ->execute() + ->fetchAllAssoc('mlid'); + + foreach ($result as $link) { + unserialize($link->title); + unserialize($link->description); + } + } + +} diff --git a/core/modules/system/src/Tests/Update/UpdatePathTestBase.php b/core/modules/system/src/Tests/Update/UpdatePathTestBase.php index d152432..a9e0ad2 100644 --- a/core/modules/system/src/Tests/Update/UpdatePathTestBase.php +++ b/core/modules/system/src/Tests/Update/UpdatePathTestBase.php @@ -141,15 +141,7 @@ protected function setUp() { // Rebuild and reset. $this->rebuildAll(); - // Remove the notices we get due to the menu link rebuild prior to running - // the system updates for the schema change. - foreach ($this->assertions as $key => $assertion) { - if ($assertion['message_group'] == 'Notice' && basename($assertion['file']) == 'MenuTreeStorage.php' && strpos($assertion['message'], 'unserialize(): Error at offset 0') !== FALSE) { - unset($this->assertions[$key]); - $this->deleteAssert($assertion['message_id']); - $this->results['#exception']--; - } - } + // Replace User 1 with the user created here. /** @var \Drupal\user\UserInterface $account */ $account = User::load(1); @@ -207,4 +199,21 @@ protected function runUpdates() { $this->clickLink(t('Apply pending updates')); } + /** + * {@inheritdoc} + */ + protected function rebuildAll() { + parent::rebuildAll(); + + // Remove the notices we get due to the menu link rebuild prior to running + // the system updates for the schema change. + foreach ($this->assertions as $key => $assertion) { + if ($assertion['message_group'] == 'Notice' && basename($assertion['file']) == 'MenuTreeStorage.php' && strpos($assertion['message'], 'unserialize(): Error at offset 0') !== FALSE) { + unset($this->assertions[$key]); + $this->deleteAssert($assertion['message_id']); + $this->results['#exception']--; + } + } + } + } diff --git a/core/modules/system/system.install b/core/modules/system/system.install index c3990c8..2f51cc0 100644 --- a/core/modules/system/system.install +++ b/core/modules/system/system.install @@ -1130,7 +1130,7 @@ function system_update_8001(&$sandbox = NULL) { ->condition('mlid', $menu_link['mlid']) ->execute(); - $sandbox['current'] += 50; + $sandbox['current']++;; } $sandbox['#finished'] = empty($sandbox['max']) ? 1 : ($sandbox['current'] / $sandbox['max']); @@ -1144,7 +1144,7 @@ function system_update_8001(&$sandbox = NULL) { return t('Menu links converted'); } else { - return t('Menu link conversion skipped'); + return t('Menu link conversion skipped, because the {menu_tree} table did not existed yet.'); } } diff --git a/core/modules/system/tests/modules/menu_test/menu_test.links.menu.yml b/core/modules/system/tests/modules/menu_test/menu_test.links.menu.yml index 914fbd5..613bc92 100644 --- a/core/modules/system/tests/modules/menu_test/menu_test.links.menu.yml +++ b/core/modules/system/tests/modules/menu_test/menu_test.links.menu.yml @@ -79,3 +79,7 @@ menu_test.child: title: 'Test menu_name child' route_name: menu_test.menu_name_test parent: menu_test.parent + +menu_test.unsafe: + route_name: menu_test.menu_name_test + deriver: '\Drupal\menu_test\Plugin\Derivative\MenuLinkTestWithUnsafeTitle' diff --git a/core/modules/system/tests/modules/menu_test/src/Plugin/Derivative/MenuLinkTestWithUnsafeTitle.php b/core/modules/system/tests/modules/menu_test/src/Plugin/Derivative/MenuLinkTestWithUnsafeTitle.php new file mode 100644 index 0000000..a9d9041 --- /dev/null +++ b/core/modules/system/tests/modules/menu_test/src/Plugin/Derivative/MenuLinkTestWithUnsafeTitle.php @@ -0,0 +1,30 @@ +derivatives['unsafe'] = [ + 'title' => '', + 'menu_name' => 'tools', + ] + $base_plugin_definition; + + return $this->derivatives; + } + + +}