Commit c267836c authored by catch's avatar catch
Browse files

Issue #2593481 by Wim Leers: PlaceholderGenerator::createPlaceholder()...

Issue #2593481 by Wim Leers: PlaceholderGenerator::createPlaceholder() generates invalid markup; causes placeholders to not be replaced if processed by DOMDocument
parent 5c5ceccc
Loading
Loading
Loading
Loading
+2 −1
Changes for core/lib/Drupal/Core/Render/PlaceholderGenerator.php: 2 added lines, 1 removed line.
Original line number Diff line number Diff line
@@ -7,6 +7,7 @@

namespace Drupal\Core\Render;

use Drupal\Component\Utility\Html;
use Drupal\Component\Utility\UrlHelper;
use Drupal\Core\Cache\Cache;

@@ -89,7 +90,7 @@ public function createPlaceholder(array $element) {
    $callback = $placeholder_render_array['#lazy_builder'][0];
    $arguments = UrlHelper::buildQuery($placeholder_render_array['#lazy_builder'][1]);
    $token = hash('crc32b', serialize($placeholder_render_array));
    $placeholder_markup = '<drupal-render-placeholder callback="' . $callback . '" arguments="' . $arguments . '" token="' . $token . '"></drupal-render-placeholder>';
    $placeholder_markup = '<drupal-render-placeholder callback="' . Html::escape($callback) . '" arguments="' . Html::escape($arguments) . '" token="' . Html::escape($token) . '"></drupal-render-placeholder>';

    // Build the placeholder element to return.
    $placeholder_element = [];
+4 −6
Changes for core/modules/filter/src/FilterProcessResult.php: 4 added lines, 6 removed lines.
Original line number Diff line number Diff line
@@ -138,12 +138,10 @@ public function setProcessedText($processed_text) {
   */
  public function createPlaceholder($callback, array $args) {
    // Generate placeholder markup.
    // @see \Drupal\Core\Render\Renderer::createPlaceholder()
    $attributes = new Attribute();
    $attributes['callback'] = $callback;
    $attributes['arguments'] = UrlHelper::buildQuery($args);
    $attributes['token'] = hash('sha1', serialize([$callback, $args]));
    $placeholder_markup = Html::normalize('<drupal-filter-placeholder' . $attributes . '></drupal-filter-placeholder>');
    // @see \Drupal\Core\Render\PlaceholderGenerator::createPlaceholder()
    $arguments = UrlHelper::buildQuery($args);
    $token = hash('crc32b', serialize([$callback, $args]));
    $placeholder_markup = '<drupal-filter-placeholder callback="' . Html::escape($callback) . '" arguments="' . Html::escape($arguments) . '" token="' . Html::escape($token) . '"></drupal-filter-placeholder>';

    // Add the placeholder attachment.
    $this->addAttachments([
+59 −0
Changes for core/tests/Drupal/Tests/Core/Render/PlaceholderGeneratorTest.php: 59 added lines, 0 removed lines.
Original line number Diff line number Diff line
<?php

/**
 * @file
 * Contains \Drupal\Tests\Core\Render\PlaceholderGeneratorTest.
 */

namespace Drupal\Tests\Core\Render;

use Drupal\Component\Utility\Html;
use Drupal\Core\Render\Element;

/**
 * @coversDefaultClass \Drupal\Core\Render\PlaceholderGenerator
 * @group Render
 */
class PlaceholderGeneratorTest extends RendererTestBase {

  /**
   * The tested placeholder generator.
   *
   * @var \Drupal\Core\Render\PlaceholderGenerator
   */
  protected $placeholderGenerator;

  /**
   * @covers ::createPlaceholder
   * @dataProvider providerCreatePlaceholderGeneratesValidHtmlMarkup
   *
   * Ensure that the generated placeholder markup is valid. If it is not, then
   * simply using DOMDocument on HTML that contains placeholders may modify the
   * placeholders' markup, which would make it impossible to replace the
   * placeholders: the placeholder markup in #attached versus that in the HTML
   * processed by DOMDocument would no longer match.
   */
  public function testCreatePlaceholderGeneratesValidHtmlMarkup(array $element) {
    $build = $this->placeholderGenerator->createPlaceholder($element);

    $original_placeholder_markup = (string)$build['#markup'];
    $processed_placeholder_markup = Html::serialize(Html::load($build['#markup']));

    $this->assertEquals($original_placeholder_markup, $processed_placeholder_markup);
  }

  /**
   * @return array
   */
  public function providerCreatePlaceholderGeneratesValidHtmlMarkup() {
    return [
      'multiple-arguments' => [['#lazy_builder' => ['Drupal\Tests\Core\Render\PlaceholdersTest::callback', ['foo', 'bar']]]],
      'special-character-&' => [['#lazy_builder' => ['Drupal\Tests\Core\Render\PlaceholdersTest::callback', ['foo&bar']]]],
      'special-character-"' => [['#lazy_builder' => ['Drupal\Tests\Core\Render\PlaceholdersTest::callback', ['foo"bar']]]],
      'special-character-<' => [['#lazy_builder' => ['Drupal\Tests\Core\Render\PlaceholdersTest::callback', ['foo<bar']]]],
      'special-character->' => [['#lazy_builder' => ['Drupal\Tests\Core\Render\PlaceholdersTest::callback', ['foo>bar']]]],
    ];

  }

}