diff --git a/src/Item/FieldTrait.php b/src/Item/FieldTrait.php index e060848..727c6ab 100644 --- a/src/Item/FieldTrait.php +++ b/src/Item/FieldTrait.php @@ -8,6 +8,7 @@ namespace Drupal\search_api\Item; use Drupal\Component\Render\FormattableMarkup; +use Drupal\Component\Utility\Html; use Drupal\search_api\Entity\Index; use Drupal\search_api\IndexInterface; use Drupal\search_api\SearchApiException; @@ -317,7 +318,7 @@ trait FieldTrait { if (isset($this->datasourceId)) { $this->labelPrefix = $this->datasourceId; try { - $this->labelPrefix = $this->getDatasource()->label(); + $this->labelPrefix = Html::escape($this->getDatasource()->label()); } catch (SearchApiException $e) { watchdog_exception('search_api', $e); @@ -325,7 +326,7 @@ trait FieldTrait { $this->labelPrefix .= ' » '; } } - return $this->labelPrefix . $this->getLabel(); + return $this->labelPrefix . Html::escape($this->getLabel()); } /** diff --git a/src/Tests/IntegrationTest.php b/src/Tests/IntegrationTest.php index 01672b7..20d5cb6 100644 --- a/src/Tests/IntegrationTest.php +++ b/src/Tests/IntegrationTest.php @@ -44,7 +44,12 @@ class IntegrationTest extends WebTestBase { /** * {@inheritdoc} */ - public static $modules = array('node', 'search_api', 'search_api_test_backend', 'field_ui'); + public static $modules = array( + 'node', + 'search_api', + 'search_api_test_backend', + 'field_ui', + ); /** * {@inheritdoc} @@ -153,8 +158,10 @@ class IntegrationTest extends WebTestBase { /** * Tests creating a search server via the UI. */ - protected function createServer() { - $this->serverId = Unicode::strtolower($this->randomMachineName()); + protected function createServer($server_id = '_test_server') { + $this->serverId = $server_id; + $server_name = 'Search API &{}<>! Server'; + $server_description = 'A >server< used for testing &.'; $settings_path = $this->urlGenerator->generateFromRoute('entity.search_api_server.add_form', array(), array('absolute' => TRUE)); $this->drupalGet($settings_path); @@ -171,19 +178,19 @@ class IntegrationTest extends WebTestBase { $this->assertText($this->t('@name field is required.', array('@name' => $this->t('Server name')))); $edit = array( - 'name' => 'Search API test server', + 'name' => $server_name, 'status' => 1, - 'description' => 'A server used for testing.', + 'description' => $server_description, 'backend' => 'search_api_test_backend', ); $this->drupalPostForm($settings_path, $edit, $this->t('Save')); $this->assertText($this->t('@name field is required.', array('@name' => $this->t('Machine-readable name')))); $edit = array( - 'name' => 'Search API test server', + 'name' => $server_name, 'id' => $this->serverId, 'status' => 1, - 'description' => 'A server used for testing.', + 'description' => $server_description, 'backend' => 'search_api_test_backend', ); @@ -191,6 +198,12 @@ class IntegrationTest extends WebTestBase { $this->assertText($this->t('The server was successfully saved.')); $this->assertUrl('admin/config/search/search-api/server/' . $this->serverId, array(), 'Correct redirect to server page.'); + $this->checkHtmlEscaping($server_name); + $this->checkHtmlEscaping($server_description); + + $this->drupalGet('admin/config/search/search-api'); + $this->checkHtmlEscaping($server_name); + $this->checkHtmlEscaping($server_description); } /** @@ -198,12 +211,15 @@ class IntegrationTest extends WebTestBase { */ protected function createIndex() { $settings_path = $this->urlGenerator->generateFromRoute('entity.search_api_index.add_form', array(), array('absolute' => TRUE)); + $this->indexId = 'test_index'; + $index_description = 'An >index< used for &! tęsting.'; + $index_name = 'Search >API< test &!^* index'; $this->drupalGet($settings_path); $this->assertResponse(200); $edit = array( 'status' => 1, - 'description' => 'An index used for testing.', + 'description' => $index_description, ); $this->drupalPostForm(NULL, $edit, $this->t('Save')); @@ -211,13 +227,12 @@ class IntegrationTest extends WebTestBase { $this->assertText($this->t('@name field is required.', array('@name' => $this->t('Machine-readable name')))); $this->assertText($this->t('@name field is required.', array('@name' => $this->t('Data sources')))); - $this->indexId = 'test_index'; $edit = array( - 'name' => 'Search API test index', + 'name' => $index_name, 'id' => $this->indexId, 'status' => 1, - 'description' => 'An index used for testing.', + 'description' => $index_description, 'server' => $this->serverId, 'datasources[]' => array('entity:node'), ); @@ -226,6 +241,10 @@ class IntegrationTest extends WebTestBase { $this->assertText($this->t('The index was successfully saved.')); $this->assertUrl($this->getIndexPath(), array(), 'Correct redirect to index page.'); + $this->checkHtmlEscaping($index_name); + + $this->drupalGet($this->getIndexPath('edit')); + $this->checkHtmlEscaping($index_name); $this->indexStorage->resetCache(array($this->indexId)); /** @var $index \Drupal\search_api\IndexInterface */ @@ -254,6 +273,10 @@ class IntegrationTest extends WebTestBase { $this->indexStorage->resetCache(array($index2_id)); $index = $this->indexStorage->load($index2_id); $this->assertUrl($index->urlInfo('fields'), array(), 'Correct redirect to index fields page.'); + + $this->drupalGet('admin/config/search/search-api'); + $this->checkHtmlEscaping($index_name); + $this->checkHtmlEscaping($index_description); } /** @@ -644,7 +667,7 @@ class IntegrationTest extends WebTestBase { $this->assertEqual($remaining_items, 0, 'All items have been successfully indexed.'); // Create a second search server. - $this->createServer(); + $this->createServer('test_server_2'); // Change the index's server to the new one. $settings_path = $this->getIndexPath('edit');