split off from #2506479: Replace !placeholder with @placeholder for non URLs in t() in Views, except for t() output that is used as an attribute value.

Problem/Motivation

We have 2 remaining usages of !placeholder in views.views.inc in imploded lists

Proposed resolution

Use @placeholder and htmlspecialchars_decode to undo the escaping caused by the assumption of t() that it is dealing with markup as opposed to plain text (as is the case here)

Remaining tasks

Review patch

User interface changes

None

API changes

None

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

Wim Leers created an issue. See original summary.

izus’s picture

Assigned: Unassigned » izus

will give it a try this night

izus’s picture

Assigned: izus » Unassigned
Status: Active » Needs review
FileSize
7.51 KB

Status: Needs review » Needs work

The last submitted patch, 3: views_ui-replace_placeholder-2571935-3.patch, failed testing.

izus’s picture

Status: Needs work » Needs review
FileSize
5.22 KB

Status: Needs review » Needs work

The last submitted patch, 5: views_ui-replace_placeholder-2571935-5.patch, failed testing.

izus’s picture

Status: Needs work » Needs review
FileSize
4.1 KB
joelpittet’s picture

Thank you @izus, just missing one more set for !display_title.

Status: Needs review » Needs work

The last submitted patch, 8: replace_placeholder-2571935-8.patch, failed testing.

stefan.r’s picture

ehhh I think we got the issue summary wrong here? This is all already being addressed in #2506479: Replace !placeholder with @placeholder for non URLs in t() in Views, except for t() output that is used as an attribute value, we're merely splitting out the comma implode, which is postponed on having a helper for suffixing strings

stefan.r’s picture

Title: Replace !placeholder with @placeholder for help strings in t() in the Views UI, except for t() output that is used as an attribute value » Fix use of !placeholder for imploding in views.views.inc
Issue summary: View changes
Status: Needs work » Postponed
Issue tags: +Needs issue summary update

The last submitted patch, 3: views_ui-replace_placeholder-2571935-3.patch, failed testing.

Status: Postponed » Needs work

The last submitted patch, 8: replace_placeholder-2571935-8.patch, failed testing.

dawehner’s picture

Status: Needs work » Postponed

Let's be clear

lauriii’s picture

stefan.r’s picture

Sorry there was a confusion on IRC about what this is blocked by.

Discussed with @alexpott and we can actually use htmlspecialchars_decode here as a workaround - it should be the only place in core where we do this. The help key is schema-type information that ought to be plain-text only, as it is used both to be plan-text help information as well as to be UI help text.

stefan.r’s picture

Issue summary: View changes
Status: Active » Needs review
Issue tags: -Needs issue summary update
FileSize
4.34 KB

Status: Needs review » Needs work

The last submitted patch, 17: 2506479-17.patch, failed testing.

The last submitted patch, 17: 2506479-17.patch, failed testing.

stefan.r’s picture

Status: Needs work » Needs review
FileSize
4.34 KB
dawehner’s picture

Here is an additional integration level testing.

alexpott’s picture

+++ b/core/modules/views_ui/src/Tests/HandlerTest.php
@@ -137,6 +139,40 @@ public function testUICRUD() {
+      'label' => 'The giraffe" label <script>alert("the return of the xss")</script>'
...
+    $this->assertText('Appears in: page, article. Also known as: Content: The giraffe" label alert("the return of the xss")');

It is odd that this is Xss filtered and not escaped as I would have expected.

stefan.r’s picture

Maybe because htmlspecialchars_decode() undoes quotes but also turns &lt;script&gt; into <script>, which gets filtered out whenever the field help text goes into #markup... @dawehner is that possible? I could look with a debugger?

dawehner’s picture

@alexpott
The reason is the following:

          $form['options']['name'][$key] = array(
            '#type' => 'checkbox',
            '#title' => $this->t('@group: @field', array('@group' => $option['group'], '@field' => $option['title'])),
            '#description' => $option['help'],

... Its using #description which is maybe like #markup

damiankloip’s picture

Status: Needs review » Reviewed & tested by the community

Spoke with multiple people about this. It's a necessary evil for now. This is more an oversight/architecture problem in views that our UI string is defined in the views data.

alexpott’s picture

Status: Reviewed & tested by the community » Needs work

Okay so we have a problem because of the #description which does not auto-escape. It is admin filtered. This makes the documentation added incorrect and it also makes the behaviour incorrect. If you put em tags in the field labels they should always be escaped but they are not here :(

I really don't like the behaviour of #description - it feels like it should auto-escape by default. If we don't want to fix this - and that would be understand since it would be a big change now - I think we have to create another SafeStringInterface object to help building view data.

I've created #2573743: #description should escape by default to explore making #description auto-escape.

stefan.r’s picture

I'm not clear how the child is blocking, where specifically would em be a problem?

I think this shows we need better tools for concatenating strings. It's not the first time we encounter this problem?

stefan.r’s picture

FWIW we had another patch earlier in #2506479: Replace !placeholder with @placeholder for non URLs in t() in Views, except for t() output that is used as an attribute value containing an array of markup arrays.

If we had #2554073: Allow #markup to be an array of strings and join them safely we'd be able to use just that and generate the help string without markup

alexpott’s picture

+++ b/core/modules/views_ui/src/Tests/HandlerTest.php
@@ -137,6 +139,40 @@ public function testUICRUD() {
+      'label' => 'The giraffe" label <script>alert("the return of the xss")</script>'
...
+    $this->assertText('Appears in: page, article. Also known as: Content: The giraffe" label alert("the return of the xss")');

In every other context the script tags would be escaped. We're stripping them here because #description is admin filtered. The problem we have is that we need to mix markup and escaping - since a translator might need to add HTML to a translation.

alexpott’s picture

Assigned: Unassigned » alexpott

I'm working on this.

alexpott’s picture

Status: Needs work » Needs review
FileSize
4.31 KB
6.4 KB

This approach preserves the escaping and makes the way labels are escaped consistent with other places in the Views and Field UI. With the previous approach if a field label contained em tags they would be escaped in the Field UI but in this help text the em tags would not have been filtered or escaped.

The only reason this works is because #description is XSS admin filtered. And therefore the fact that the final string is not marked safe does not cause double escaping.

alexpott’s picture

Assigned: alexpott » Unassigned
stefan.r’s picture

+++ b/core/modules/views/views.views.inc
@@ -550,7 +559,17 @@ function views_field_default_views_data(FieldStorageConfigInterface $field_stora
+        $data[$table_alias][$column_real_name]['help'] .= ' ' . t('Also known as:') . ' ' . $also_known_list;

This bit doesn't have tests does it? Do we need the htmlspecialchars_decode()?

Wim Leers’s picture

This looks great! (And I trust Alex is best judge of how to approach this.)

  1. +++ b/core/modules/views/src/Tests/FieldApiDataTest.php
    @@ -26,9 +27,20 @@ protected function setUp() {
    +    $field = FieldConfig::create([
    ...
    +    $field->save();
    

    No point in assigning to a variable, can just be FieldConfig::create([…])->save().

  2. +++ b/core/modules/views/views.views.inc
    @@ -449,7 +449,16 @@ function views_field_default_views_data(FieldStorageConfigInterface $field_stora
    +      // The $also_known variable contains markup that is HTML escaped and that
    

    "markup that is HTML escaped" sounds very strange. "escaped HTML" or "Html::escape()d" would make sense.

  3. +++ b/core/modules/views/views.views.inc
    @@ -449,7 +449,16 @@ function views_field_default_views_data(FieldStorageConfigInterface $field_stora
    +      // and therefore XSS admin filtered by default. Escaped HTML is not
    

    Similar thing with "XSS admin filtered" here.

  4. +++ b/core/modules/views/views.views.inc
    @@ -550,7 +559,17 @@ function views_field_default_views_data(FieldStorageConfigInterface $field_stora
    +        // The $also_known variable contains markup that is HTML escaped and that
    ...
    +        // escape the data on output. We do this here because what we are putting
    

    80 cols violations.

  5. +++ b/core/modules/views/views.views.inc
    @@ -449,7 +449,16 @@ function views_field_default_views_data(FieldStorageConfigInterface $field_stora
    +      // strings. Ideally the result would also by marked safe so that, if the
    

    s/by/be/

  6. +++ b/core/modules/views_ui/src/Tests/HandlerTest.php
    @@ -138,6 +140,43 @@ public function testUICRUD() {
    +    $field_storage = FieldStorageConfig::create([
    ...
    +    $field_storage->save();
    ...
    +    $field_config = FieldConfig::create([
    ...
    +    $field_config->save();
    ...
    +    $field_config = FieldConfig::create([
    ...
    +    $field_config->save();
    

    Same here.


Fixed everything except points 2 and 3, which I defer to Alex, a native speaker. :)

dawehner’s picture

Workign on the discussion we had during drupalcon

Wim Leers’s picture

Assigned: Unassigned » dawehner
Status: Needs review » Needs work
dawehner’s picture

Assigned: dawehner » Unassigned
Status: Needs work » Needs review
FileSize
7.02 KB
4.91 KB

There we go. We make it a safe string, as we know it is safe.

jhedstrom’s picture

I think the patches in #38 and #39 are for a different issue?

jhedstrom’s picture

Status: Needs review » Reviewed & tested by the community

I think the above concerns have been addressed, the patch in #37 looks good.

The last submitted patch, 38: fix_use_of_placeholder-2571935-38.patch, failed testing.

alexpott’s picture

Status: Reviewed & tested by the community » Fixed

Discussed with @dawehner, @xjm, @laurii, @joelpittet, and @stefan.r. It is a shame that we have to do this but creating UI text at the point of building the schema information makes this very very tricky. Committed 36b936f and pushed to 8.0.x. Thanks!

  • alexpott committed 36b936f on 8.0.x
    Issue #2571935 by izus, dawehner, stefan.r, alexpott, Wim Leers,...

Status: Fixed » Needs work

The last submitted patch, fix_use_of_placeholder-2571935-39.patch, failed testing.

lauriii’s picture

Status: Needs work » Fixed

The last submitted patch, 37: 2571935-36.patch, failed testing.

The last submitted patch, fix_use_of_placeholder-2571935-38.patch, failed testing.

Status: Fixed » Needs work

The last submitted patch, fix_use_of_placeholder-2571935-39.patch, failed testing.

alexpott’s picture

Status: Needs work » Fixed

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.