Merge branch 'MDL-87482-main' of https://github.com/HuongNV13/moodle
This commit is contained in:
@@ -304,7 +304,9 @@ class formatting {
|
||||
if ($blanktarget) {
|
||||
$domdoc = new \DOMDocument();
|
||||
libxml_use_internal_errors(true);
|
||||
$domdoc->loadHTML('<?xml version="1.0" encoding="UTF-8" ?>' . $text);
|
||||
// Use meta charset tag to properly handle UTF-8 instead of XML declaration hack.
|
||||
// The XML declaration approach no longer works with libxml2 >= 2.14.0.
|
||||
$domdoc->loadHTML('<meta http-equiv="Content-Type" content="text/html; charset=utf-8">' . $text);
|
||||
libxml_clear_errors();
|
||||
foreach ($domdoc->getElementsByTagName('a') as $link) {
|
||||
if ($link->hasAttribute('target') && strpos($link->getAttribute('target'), '_blank') === false) {
|
||||
@@ -320,11 +322,23 @@ class formatting {
|
||||
// $domdoc->loadHTML($text, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD); however it seems like some libxml
|
||||
// versions don't work properly and end up leaving <html><body>, so I'm forced to use
|
||||
// this regex to remove those tags as a preventive measure.
|
||||
// Also strip head and meta tags added by the charset workaround.
|
||||
$text = trim(preg_replace(
|
||||
'~<(?:!DOCTYPE|/?(?:html|body))[^>]*>\s*~i',
|
||||
'~<(?:!DOCTYPE|/?(?:html|head|body)|meta\s[^>]*?)>\s*~i',
|
||||
'',
|
||||
$domdoc->saveHTML($domdoc->documentElement),
|
||||
));
|
||||
// Libxml2 >= 2.14.0 doesn't wrap plain text in <p> tags, so add them for consistency.
|
||||
if (LIBXML_VERSION >= 21400) {
|
||||
$trimmed = trim($text);
|
||||
if ($trimmed !== '' && !preg_match('/^</', $trimmed)) {
|
||||
$text = '<p>' . $text . '</p>';
|
||||
}
|
||||
}
|
||||
// The meta charset approach preserves leading/trailing whitespace in <p> tags more than the old XML
|
||||
// declaration approach. Normalize this by trimming whitespace inside <p> tags to match old behavior.
|
||||
$text = preg_replace('~<p>\s+~i', '<p>', $text);
|
||||
$text = preg_replace('~\s+</p>~i', '</p>', $text);
|
||||
}
|
||||
|
||||
return $text;
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -225,7 +225,8 @@ function(
|
||||
if (!isMedia) {
|
||||
// Try to get the text value of the content.
|
||||
// If that's not possible, we'll report it under the catch-all 'other media'.
|
||||
var messagePreview = $(lastMessage.text).text();
|
||||
// Use textContent to safely extract text without jQuery selector parsing.
|
||||
var messagePreview = tmpElement.textContent || tmpElement.innerText || '';
|
||||
if (messagePreview) {
|
||||
// The text value of the message must have no html/script tags.
|
||||
if (messagePreview.indexOf('<') == -1) {
|
||||
|
||||
@@ -687,13 +687,25 @@ class helper {
|
||||
if (!empty($message)) {
|
||||
$doc = new DOMDocument();
|
||||
$olderror = libxml_use_internal_errors(true);
|
||||
$doc->loadHTML('<?xml version="1.0" encoding="UTF-8" ?>' . $message);
|
||||
// Use meta charset tag to properly handle UTF-8 instead of XML declaration hack.
|
||||
// The XML declaration approach no longer works with libxml2 >= 2.14.0.
|
||||
$doc->loadHTML('<meta http-equiv="Content-Type" content="text/html; charset=utf-8">' . $message);
|
||||
libxml_clear_errors();
|
||||
libxml_use_internal_errors($olderror);
|
||||
$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);
|
||||
$body = $doc->getElementsByTagName('body')->item(0);
|
||||
if ($body) {
|
||||
$html = $body->C14N(false, true);
|
||||
if ($removebody) {
|
||||
// Remove <body> element added in C14N function.
|
||||
$html = preg_replace('~<(/?(?:body))[^>]*>\s*~i', '', $html);
|
||||
// Libxml2 >= 2.14.0 doesn't wrap plain text in <p> tags, so add them for consistency.
|
||||
if (LIBXML_VERSION >= 21400) {
|
||||
$trimmed = trim($html);
|
||||
if ($trimmed !== '' && !preg_match('/^</', $trimmed)) {
|
||||
$html = '<p>' . $html . '</p>';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -221,6 +221,13 @@ final class helper_test extends \advanced_testcase {
|
||||
$this->setAdminUser();
|
||||
|
||||
$html = \core_message\helper::prevent_unclosed_html_tags($message, $removebody);
|
||||
|
||||
// Libxml2 >= 2.14.0 closes unclosed comments instead of removing them.
|
||||
// Check if we're testing the unclosed comment case and adjust expectation based on libxml version.
|
||||
if ($message === '<h1>Title</h1><p>Paragraph</p><!-- Comments' && LIBXML_VERSION >= 21400) {
|
||||
$goodhtml = '<h1>Title</h1><p>Paragraph</p><!-- Comments-->';
|
||||
}
|
||||
|
||||
$this->assertSame($goodhtml, $html);
|
||||
}
|
||||
|
||||
@@ -248,6 +255,12 @@ final class helper_test extends \advanced_testcase {
|
||||
'Check encoding UTF-8 is working' => [
|
||||
'<body><h1>Title</h1><p>السلام عليكم</p></body>', '<body><h1>Title</h1><p>السلام عليكم</p></body>', false
|
||||
],
|
||||
'Script tag only returns empty' => [
|
||||
'<script>alert("test")</script>', '', true,
|
||||
],
|
||||
'Script tag with text' => [
|
||||
'<script>alert("test")</script>Some text', '<p>Some text</p>', true,
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user