Commit c57b3db6 authored by webchick's avatar webchick

Issue #2309215 by googletorp, subhojit777, lokeoke, tadityar, crowdcg, aneek,...

Issue #2309215 by googletorp, subhojit777, lokeoke, tadityar, crowdcg, aneek, joelpittet, jhedstrom, alexpott, lauriii, amankanoria: HTML double-escaping in revision messages
parent eb3e64a0
......@@ -172,53 +172,66 @@ public function revisionOverview(NodeInterface $node) {
$vids = $node_storage->revisionIds($node);
foreach (array_reverse($vids) as $vid) {
if ($revision = $node_storage->loadRevision($vid)) {
$row = array();
$revision_author = $revision->uid->entity;
if ($vid == $node->getRevisionId()) {
$username = array(
'#theme' => 'username',
'#account' => $revision_author,
);
$row[] = array('data' => $this->t('!date by !username', array('!date' => $node->link($this->dateFormatter->format($revision->revision_timestamp->value, 'short')), '!username' => drupal_render($username)))
. (($revision->revision_log->value != '') ? '<p class="revision-log">' . Xss::filter($revision->revision_log->value) . '</p>' : ''),
'class' => array('revision-current'));
$row[] = array('data' => SafeMarkup::placeholder($this->t('current revision')), 'class' => array('revision-current'));
$revision = $node_storage->loadRevision($vid);
$username = [
'#theme' => 'username',
'#account' => $revision->uid->entity,
];
// Use revision link to link to revisions that are not active.
$date = $this->dateFormatter->format($revision->revision_timestamp->value, 'short');
if ($vid != $node->getRevisionId()) {
$link = $this->l($date, new Url('entity.node.revision', ['node' => $node->id(), 'node_revision' => $vid]));
}
else {
$link = $node->link($date);
}
$row = [];
$row[] = [
'data' => [
'#type' => 'inline_template',
'#template' => '{% trans %}{{ date }} by {{ username }}{% endtrans %}{% if message %}<p class="revision-log">{{ message }}</p>{% endif %}',
'#context' => [
'date' => $link,
'username' => $this->renderer->render($username),
'message' => Xss::filter($revision->revision_log->value),
],
],
];
if ($vid == $node->getRevisionId()) {
$row[0]['class'] = ['revision-current'];
$row[] = [
'data' => SafeMarkup::placeholder($this->t('current revision')),
'class' => ['revision-current'],
];
}
else {
$links = [];
if ($revert_permission) {
$links['revert'] = [
'title' => $this->t('Revert'),
'url' => Url::fromRoute('node.revision_revert_confirm', ['node' => $node->id(), 'node_revision' => $vid]),
];
}
else {
$username = array(
'#theme' => 'username',
'#account' => $revision_author,
);
$row[] = $this->t('!date by !username', array('!date' => $this->l($this->dateFormatter->format($revision->revision_timestamp->value, 'short'), new Url('entity.node.revision', array('node' => $node->id(), 'node_revision' => $vid))), '!username' => drupal_render($username)))
. (($revision->revision_log->value != '') ? '<p class="revision-log">' . Xss::filter($revision->revision_log->value) . '</p>' : '');
if ($revert_permission) {
$links['revert'] = array(
'title' => $this->t('Revert'),
'url' => Url::fromRoute('node.revision_revert_confirm', ['node' => $node->id(), 'node_revision' => $vid]),
);
}
if ($delete_permission) {
$links['delete'] = array(
'title' => $this->t('Delete'),
'url' => Url::fromRoute('node.revision_delete_confirm', ['node' => $node->id(), 'node_revision' => $vid]),
);
}
$row[] = array(
'data' => array(
'#type' => 'operations',
'#links' => $links,
),
);
if ($delete_permission) {
$links['delete'] = [
'title' => $this->t('Delete'),
'url' => Url::fromRoute('node.revision_delete_confirm', ['node' => $node->id(), 'node_revision' => $vid]),
];
}
$rows[] = $row;
$row[] = [
'data' => [
'#type' => 'operations',
'#links' => $links,
],
];
}
$rows[] = $row;
}
$build['node_revisions_table'] = array(
......
......@@ -7,6 +7,8 @@
namespace Drupal\node\Tests;
use Drupal\Core\Url;
use Drupal\node\Entity\Node;
use Drupal\node\Entity\NodeType;
/**
......@@ -16,27 +18,31 @@
*/
class NodeRevisionsUiTest extends NodeTestBase {
/**
* @var \Drupal\user\Entity\User
*/
protected $editor;
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
// Create and log in user.
$web_user = $this->drupalCreateUser(
array(
'administer nodes',
'edit any page content'
)
);
$this->drupalLogin($web_user);
// Create users.
$this->editor = $this->drupalCreateUser([
'administer nodes',
'edit any page content',
'view page revisions',
'access user profiles',
]);
}
/**
* Checks that unchecking 'Create new revision' works when editing a node.
*/
function testNodeFormSaveWithoutRevision() {
$this->drupalLogin($this->editor);
$node_storage = $this->container->get('entity.manager')->getStorage('node');
// Set page revision setting 'create new revision'. This will mean new
......@@ -73,6 +79,60 @@ function testNodeFormSaveWithoutRevision() {
$node_storage->resetCache(array($node->id()));
$node_revision = $node_storage->load($node->id());
$this->assertNotEqual($node_revision->getRevisionId(), $node->getRevisionId(), "After an existing node is saved with 'Create new revision' checked, a new revision is created.");
}
/**
* Checks HTML double escaping of revision logs.
*/
public function testNodeRevisionDoubleEscapeFix() {
$this->drupalLogin($this->editor);
$nodes = [];
// Create the node.
$node = $this->drupalCreateNode();
$username = [
'#theme' => 'username',
'#account' => $this->editor,
];
$editor = \Drupal::service('renderer')->render($username);
// Get original node.
$nodes[] = clone $node;
// Create revision with a random title and body and update variables.
$node->title = $this->randomMachineName();
$node->body = [
'value' => $this->randomMachineName(32),
'format' => filter_default_format(),
];
$node->setNewRevision();
$revision_log = 'Revision <em>message</em> with markup.';
$node->revision_log->value = $revision_log;
$node->save();
// Make sure we get revision information.
$node = Node::load($node->id());
$nodes[] = clone $node;
$this->drupalGet('node/' . $node->id() . '/revisions');
// Assert the old revision message.
$date = format_date($nodes[0]->revision_timestamp->value, 'short');
$url = new Url('entity.node.revision', ['node' => $nodes[0]->id(), 'node_revision' => $nodes[0]->getRevisionId()]);
$old_revision_message = t('!date by !username', [
'!date' => \Drupal::l($date, $url),
'!username' => $editor,
]);
$this->assertRaw($old_revision_message);
// Assert the current revision message.
$date = format_date($nodes[1]->revision_timestamp->value, 'short');
$current_revision_message = t('!date by !username', [
'!date' => $nodes[1]->link($date),
'!username' => $editor,
]);
$current_revision_message .= '<p class="revision-log">' . $revision_log . '</p>';
$this->assertRaw($current_revision_message);
}
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment