Filter tips improperly strips markup attributes/elements.

Created on 28 January 2023, over 1 year ago

Problem/Motivation

For some versions now (including 9.x), /filter/tips has apparently been stripping attributes from the markup provided by the filter tips, causing them to be displayed incorrectly.

Steps to reproduce

Install a module that provides the following minimal filter plugin:


namespace Drupal\filtertips\Plugin\Filter;

use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\filter\Plugin\FilterBase;

/**
 * Provides a filter that converts BBCode to HTML.
 *
 * @Filter(
 *   id = "filtertips",
 *   module = "filtertips",
 *   title = @Translation("Filter Tips"),
 *   description = @Translation("Filter Tips"),
 *   type = Drupal\filter\Plugin\FilterInterface::TYPE_MARKUP_LANGUAGE,
 *   settings = {
 *     "linebreaks" = TRUE,
 *     "tags" = "",
 *     "xss" = TRUE,
 *   }
 * )
 */
class FilterTipsFilter extends FilterBase {

  public function process($text, $langcode): FilterProcessResult {
    return new FilterProcessResult($text);
  }

  public function tips($long = FALSE) {
    if ($long) {
      return '<span style="color:red">FILTER TIPS</span>';
    }
  }
}

Enable it on a text format and visit the /filter/tips page.

Expected: The string "FILTER TIPS" shows up in the filter tips in red color.

Actual: The string shows up with no style. It is in a span element that has no attributes.

As the filter plugin class is expected to return its tips markup in a bare string with no further templating or metadata, I'm not sure what else to do here to ensure the filter tips are rendered correctly.

πŸ› Bug report
Status

Active

Version

10.0 ✨

Component
FilterΒ  β†’

Last updated 2 days ago

No maintainer
Created by

πŸ‡¨πŸ‡­Switzerland cburschka

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

  • Issue created by @cburschka
  • πŸ‡ΊπŸ‡ΈUnited States cilefen

    Does the class attribute not work?

  • πŸ‡¨πŸ‡­Switzerland cburschka

    On testing further, it does seems to affect a lot of markup besides style - for example, one of my macros should do the following:

    Turn this

    [spoiler]Hidden text[/spoiler]

    into the output of this twig template:

    {% set id = random() %}
    <input id="xbbcode-spoiler-{{ id }}" type="checkbox" class="xbbcode-spoiler" />
    <label class="xbbcode-spoiler" for="xbbcode-spoiler-{{ id }}">{{ tag.content }}</label>
    {% endapply %}

    with this CSS attached:

    input.xbbcode-spoiler:not(:checked) + label.xbbcode-spoiler,
    input.xbbcode-spoiler:not(:checked) + label.xbbcode-spoiler * {
      color: black;
      background: black;
    }
    /* Hide the checkbox. */
    input.xbbcode-spoiler {
      display: none;
    }
    

    This works normally in content:

    <input id="xbbcode-spoiler-1375131070" type="checkbox" class="xbbcode-spoiler">
    <label class="xbbcode-spoiler" for="xbbcode-spoiler-1375131070">Hidden text</label>

    But (in 10.0.2) the sample output on /filter/tips removes everything except the text of the label:

    Hidden text

    Class and data attributes I tested seem to go through, but they're not really usable in this context. I suppose the markup could be inserted dynamically by a script, but that seems an overly cumbersome way to circumvent the filter.

  • πŸ‡ΊπŸ‡ΈUnited States cilefen

    Can you determine the core version that introduced the new behavior, and from there, the issue that caused the change?

  • πŸ‡¨πŸ‡­Switzerland cburschka

    Well, this was a wild goose chase :D

    After inexplicably finding this same behavior as far back as 8.6, I finally realized the issue is in my test module: My actual module here returns the result of a \Drupal::service('renderer')->render() call, rather than a string. The renderer, of course, returns a Markup object, which allows the markup and styles to pass through unscathed.

    The regression therefore was not in core - it was caused by adding return type hints in my module.

    Drupal\filter\Plugin\FilterInterface::tips() asks for the return type to be "string|null" in PHPDoc, and without type-hints, this polite suggestion causes no problem when returning a Markup object.

    If we add string as a strict type hint, though, PHP helpfully converts the Markup object back to string before returning it, causing it to be sanitized. :D

    In summary, in core this seems to be just a documentation issue for now - all such methods that expect render output should mention Drupal\Core\Render\MarkupInterface as a possible return type alongside string. Eventually as strict type hints get introduced in core (see 🌱 [Meta] Implement strict typing in existing code Active ) this could become more critical.

Production build 0.71.5 2024