diff --git a/core/modules/views/src/Tests/FieldApiDataTest.php b/core/modules/views/src/Tests/FieldApiDataTest.php index f1c1bae..a4c1142 100644 --- a/core/modules/views/src/Tests/FieldApiDataTest.php +++ b/core/modules/views/src/Tests/FieldApiDataTest.php @@ -7,6 +7,7 @@ namespace Drupal\views\Tests; +use Drupal\Component\Utility\SafeStringInterface; use Drupal\field\Entity\FieldConfig; use Drupal\field\Tests\Views\FieldTestBase; @@ -97,7 +98,12 @@ function testViewsData() { $this->assertTrue($data[$current_table][$field_storage->getName()]['field']['click sortable'], 'String field is click sortable.'); // Click sort should only be on the primary field. $this->assertTrue(empty($data[$revision_table][$field_storage->getName()]['field']['click sortable']), 'Non-primary fields are not click sortable'); + + $this->assertTrue($data[$current_table][$field_storage->getName()]['help'] instanceof SafeStringInterface); $this->assertEqual($data[$current_table][$field_storage->getName()]['help'], 'Appears in: page, article. Also known as: Content: The giraffe2" label'); + + $this->assertTrue($data[$current_table][$field_storage->getName() . '_value']['help'] instanceof SafeStringInterface); + $this->assertEqual($data[$current_table][$field_storage->getName() . '_value']['help'], 'Appears in: page, article. Also known as: Content: The giraffe" label (field_name_0)'); } } diff --git a/core/modules/views/views.views.inc b/core/modules/views/views.views.inc index 6c9fa5c..2d4a95d 100644 --- a/core/modules/views/views.views.inc +++ b/core/modules/views/views.views.inc @@ -8,6 +8,7 @@ use Drupal\Component\Utility\NestedArray; use Drupal\Core\Entity\EntityStorageInterface; use Drupal\Core\Entity\Sql\SqlContentEntityStorage; +use Drupal\Core\Render\SafeString; use Drupal\field\FieldConfigInterface; use Drupal\field\FieldStorageConfigInterface; use Drupal\system\ActionConfigEntityInterface; @@ -453,12 +454,12 @@ function views_field_default_views_data(FieldStorageConfigInterface $field_stora // loses safeness when imploded. The help text is used in #description // and therefore XSS admin filtered by default. Escaped HTML is not // altered by XSS filtering, therefore it is safe to just concatenate the - // strings. Ideally the result would also be marked safe so that, if the - // string is used in another context it would not be escaped again. + // strings. Afterwards we mark the entire string as safe, so it won't be + // escaped, no matter where it is used. // Considering the dual use of this help data (both as metadata and as // help text), other patterns such as use of #markup would not be correct // here. - $data[$table_alias][$field_alias]['help'] .= ' ' . t('Also known as:') . ' ' . implode(', ', $also_known); + $data[$table_alias][$field_alias]['help'] = SafeString::create($data[$table_alias][$field_alias]['help'] . ' ' . t('Also known as:') . ' ' . implode(', ', $also_known)); } $keys = array_keys($field_columns); @@ -560,16 +561,15 @@ function views_field_default_views_data(FieldStorageConfigInterface $field_stora if ($aliases) { $data[$table_alias][$column_real_name]['aliases'] = $aliases; // The $also_known variable contains markup that is HTML escaped and - // that loses safeness when imploded. In order to undo the previous - // escaping, we perform a htmlspecialchars_decode() and rely on auto- - // escape to re-escape the data on output. We do this here because what - // we are putting into the help key of the field is schema-like plain- - // text data that is not supposed to contain any markup, while t() - // outputs HTML data by default. Considering the dual use of this help - // data (both as metadata and as help text), other patterns such as use - // of #markup would not be correct here. - $also_known_list = htmlspecialchars_decode(implode(', ', $also_known), ENT_QUOTES | ENT_SUBSTITUTE); - $data[$table_alias][$column_real_name]['help'] .= ' ' . t('Also known as:') . ' ' . $also_known_list; + // that loses safeness when imploded. The help text is used in + // #description and therefore XSS admin filtered by default. Escaped + // HTML is not altered by XSS filtering, therefore it is safe to just + // concatenate the strings. Afterwards we mark the entire string as + // safe, so it won't be escaped, no matter where it is used. + // Considering the dual use of this help data (both as metadata and as + // help text), other patterns such as use of #markup would not be + // correct here. + $data[$table_alias][$column_real_name]['help'] = SafeString::create($data[$table_alias][$column_real_name]['help'] . ' ' . t('Also known as:') . ' ' . implode(', ', $also_known)); } $data[$table_alias][$column_real_name]['argument'] = array(