MDL-71919 core_message: Fix unclosed html tags in email notification

This commit is contained in:
cescobedo 2021-07-05 15:57:23 +02:00 committed by Eloy Lafuente (stronk7)
parent 65642ef97a
commit 9aa5f7fe9b
3 changed files with 74 additions and 0 deletions

View File

@ -186,10 +186,18 @@ class manager {
$localisedeventdata->fullmessage = $eventdata->fullmessage;
$localisedeventdata->fullmessagehtml = $eventdata->fullmessagehtml;
if (!empty($localisedeventdata->fullmessage)) {
// Prevent unclosed HTML elements.
$localisedeventdata->fullmessage =
\core_message\helper::prevent_unclosed_html_tags($localisedeventdata->fullmessage, true);
$localisedeventdata->fullmessage .= "\n\n---------------------------------------------------------------------\n"
. $emailtagline;
}
if (!empty($localisedeventdata->fullmessagehtml)) {
// Prevent unclosed HTML elements.
$localisedeventdata->fullmessagehtml =
\core_message\helper::prevent_unclosed_html_tags($localisedeventdata->fullmessagehtml, true);
$localisedeventdata->fullmessagehtml .=
"<br><br>---------------------------------------------------------------------<br>" . $emailtagline;
}

View File

@ -23,6 +23,7 @@
*/
namespace core_message;
use DOMDocument;
defined('MOODLE_INTERNAL') || die();
@ -678,4 +679,30 @@ class helper {
}
return [];
}
/**
* Prevent unclosed HTML elements in a message.
*
* @param string $message The html message.
* @param bool $removebody True if we want to remove tag body.
* @return string The html properly structured.
*/
public static function prevent_unclosed_html_tags(
string $message,
bool $removebody = false
) : string
{
$html = '';
if (!empty($message)) {
$doc = new DOMDocument();
@$doc->loadHTML($message);
$html = $doc->getElementsByTagName('body')->item(0)->C14N(false, true);
if ($removebody) {
// Remove <body> element added in C14N function.
$html = preg_replace('~<(/?(?:body))[^>]*>\s*~i', '', $html);
}
}
return $html;
}
}

View File

@ -177,4 +177,43 @@ class core_message_helper_testcase extends advanced_testcase {
$this->assertNotEmpty(\core_message\helper::search_get_user_details($user6)); // Teacher in same course.
$this->assertNotEmpty(\core_message\helper::search_get_user_details($user7)); // Teacher (course contact) in another course.
}
/**
* Test prevent_unclosed_html_tags returns the correct html.
*
* @dataProvider prevent_unclosed_html_tags_data
* @param string $text text to preview unclosed html tags.
* @param string $goodhtml html good structured.
* @param bool $removebody true if we want to remove tag body.
*/
public function test_prevent_unclosed_html_tags(string $message, string $goodhtml, bool $removebody) {
$this->setAdminUser();
$html = \core_message\helper::prevent_unclosed_html_tags($message, $removebody);
$this->assertSame($goodhtml, $html);
}
/**
* Data provider for the test_prevent_unclosed_html_tags_data tests.
*
* @return array
*/
public function prevent_unclosed_html_tags_data(): array {
return [
'Prevent unclosed html elements' => [
'<h1>Title</h1><p>Paragraph</p><b>Bold', '<h1>Title</h1><p>Paragraph</p><b>Bold</b>', true
],
'Prevent unclosed html elements including comments' => [
'<h1>Title</h1><p>Paragraph</p><!-- Comments //--><b>Bold', '<h1>Title</h1><p>Paragraph</p><!-- Comments //--><b>Bold</b>', true
],
'Prevent unclosed comments' => ['<h1>Title</h1><p>Paragraph</p><!-- Comments', '<h1>Title</h1><p>Paragraph</p>', true
],
'Prevent unclosed html elements without removing tag body' => [
'<body><h2>Title 2</h2><p>Paragraph</p><b>Bold</body>', '<body><h2>Title 2</h2><p>Paragraph</p><b>Bold</b></body>', false
],
'Empty html' => [
'', '', false
],
];
}
}